Skip to content

3rd order pullback improvements - #300

Open
thorek1 wants to merge 41 commits into
mainfrom
3rd_order_pullback_improvements
Open

3rd order pullback improvements#300
thorek1 wants to merge 41 commits into
mainfrom
3rd_order_pullback_improvements

Conversation

@thorek1

@thorek1 thorek1 commented Jun 7, 2026

Copy link
Copy Markdown
Owner

No description provided.

Copilot AI review requested due to automatic review settings June 7, 2026 18:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR focuses on improving performance and memory behavior in 3rd-order pullback routines by introducing more sparsity-aware adjoint kernels and by adding a sparse cotangent overload for compressed_kron³_pullback!. It also expands diagnostic output in Sylvester/Lyapunov solvers.

Changes:

  • Reworked the mixed-sparsity mul_fill_kron_adjoint! (A sparse, B dense) to use row-compressed representations and avoid large intermediate allocations / try...catch.
  • Added a sparse-∂Y overload for compressed_kron³_pullback! and refactored mul_compressed_kron³_pullback! to avoid materializing M1*M2.
  • Extended verbose solver logging (Sylvester/Lyapunov) with matrix types/sizes; minor edits in choose_matrix_format.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
src/rrules.jl New/rewritten 3rd-order pullback kernels and sparse-aware compressed_kron³_pullback!; integrates choose_matrix_format for cotangent formatting.
src/MacroModelling.jl Adds commented-out alternative sparse conversion path in choose_matrix_format (currently dead code).
src/algorithms/sylvester.jl Verbose logging now includes operand sizes/types.
src/algorithms/lyapunov.jl Verbose logging now includes operand types (and more context in Schur deflation messages).

Comment thread src/rrules.jl Outdated
Comment on lines +6706 to +6708
tol::Real = 0.0,
block::AbstractMatrix{R} = Matrix{R}(undef, size(M1, 1), 0),
) where {R <: Real, TA <: Real, TB <: Real, Ti <: Integer}
Comment thread src/rrules.jl
Comment on lines +7842 to +7846
tol_T = T(tol)

row_values = SparseArrays.rowvals(∂Y)
non_zero_values = nonzeros(∂Y)

Comment thread src/rrules.jl
Comment on lines +7890 to +7894
j2 = col_second[col]
k2 = col_third[col]

for stored_index in SparseArrays.nzrange(∂Y, col)
row = Int(row_values[stored_index])
Comment thread src/rrules.jl
ℒ.mul!(∂B_from_sylv, 𝐒₃_stable', ∂𝐗₃)
# ∂B_from_sylv = sparse(𝐒₃_stable' * ∂𝐗₃)

∂B_from_sylv = choose_matrix_format(∂B_from_sylv)
Comment thread src/MacroModelling.jl
Comment on lines +866 to +867
# a = sparse(A)
# droptol!(a, tol)
@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown

Benchmark Results

main 3eed3ae... main / 3eed3ae...
FS2000/NSSS 4.86 ± 0.068 μs 4.84 ± 0.072 μs 1 ± 0.021
FS2000/covariance 18.1 ± 1 μs 18.1 ± 1 μs 1 ± 0.079
FS2000/irf 0.0639 ± 0.013 ms 0.0737 ± 0.0059 ms 0.866 ± 0.19
FS2000/jacobian 1.01 ± 0.047 μs 1.04 ± 0.054 μs 0.975 ± 0.068
FS2000/lyapunov/bartels_stewart 0.108 ± 0.0052 ms 0.109 ± 0.0037 ms 0.99 ± 0.058
FS2000/lyapunov/bicgstab 25.6 ± 0.82 μs 25.2 ± 0.82 μs 1.02 ± 0.046
FS2000/lyapunov/doubling 0.0354 ± 0.00095 ms 0.0354 ± 0.001 ms 1 ± 0.039
FS2000/lyapunov/gmres 16.7 ± 0.19 μs 16.6 ± 0.15 μs 1.01 ± 0.015
FS2000/qme/doubling 0.097 ± 0.0015 ms 0.0974 ± 0.00097 ms 0.996 ± 0.019
FS2000/qme/schur 0.0452 ± 0.00099 ms 0.0442 ± 0.001 ms 1.02 ± 0.033
NAWM_EAUS_2008/NSSS 0.939 ± 0.02 ms 0.97 ± 0.027 ms 0.968 ± 0.034
NAWM_EAUS_2008/covariance 3.19 ± 0.52 ms 3.11 ± 0.59 ms 1.02 ± 0.26
NAWM_EAUS_2008/irf 7.34 ± 0.29 ms 7.38 ± 0.2 ms 0.994 ± 0.048
NAWM_EAUS_2008/jacobian 0.0409 ± 0.0055 ms 0.0398 ± 0.0044 ms 1.03 ± 0.18
NAWM_EAUS_2008/lyapunov/bartels_stewart 17.4 ± 0.63 ms 17.7 ± 1.1 ms 0.982 ± 0.07
NAWM_EAUS_2008/lyapunov/bicgstab 0.23 ± 9.9e-05 s 0.207 ± 0.00077 s 1.11 ± 0.0041
NAWM_EAUS_2008/lyapunov/doubling 19.5 ± 0.095 ms 19.4 ± 0.14 ms 1 ± 0.0088
NAWM_EAUS_2008/lyapunov/gmres 0.11 ± 0.00044 s 0.109 ± 0.00033 s 1.01 ± 0.0051
NAWM_EAUS_2008/qme/doubling 29.8 ± 2.8 ms 29.3 ± 0.085 ms 1.02 ± 0.097
NAWM_EAUS_2008/qme/schur 18.5 ± 0.6 ms 17.2 ± 0.045 ms 1.07 ± 0.035
Smets_Wouters_2007/NSSS 0.0559 ± 0.00098 ms 0.0651 ± 0.00099 ms 0.858 ± 0.02
Smets_Wouters_2007/covariance 0.198 ± 0.0046 ms 0.222 ± 0.0046 ms 0.891 ± 0.028
Smets_Wouters_2007/irf 0.418 ± 0.014 ms 0.466 ± 0.052 ms 0.897 ± 0.11
Smets_Wouters_2007/jacobian 9.65 ± 30 μs 8.91 ± 30 μs 1.08 ± 5
Smets_Wouters_2007/lyapunov/bartels_stewart 1.25 ± 0.0095 ms 1.25 ± 0.01 ms 1.01 ± 0.011
Smets_Wouters_2007/lyapunov/bicgstab 6.08 ± 0.0069 ms 5.77 ± 0.0076 ms 1.05 ± 0.0018
Smets_Wouters_2007/lyapunov/doubling 1.02 ± 0.003 ms 1.02 ± 0.0029 ms 0.999 ± 0.0041
Smets_Wouters_2007/lyapunov/gmres 5.03 ± 0.014 ms 5.02 ± 0.012 ms 1 ± 0.0037
Smets_Wouters_2007/qme/doubling 1.77 ± 0.0085 ms 1.76 ± 0.0082 ms 1.01 ± 0.0067
Smets_Wouters_2007/qme/schur 0.905 ± 0.0078 ms 1.05 ± 0.0085 ms 0.864 ± 0.01
time_to_load 11.3 ± 0.0075 s 11.3 ± 0.043 s 0.998 ± 0.0038
main 3eed3ae... main / 3eed3ae...
FS2000/NSSS 21 allocs: 0.855 kB 21 allocs: 0.855 kB 1
FS2000/covariance 0.134 k allocs: 17.2 kB 0.134 k allocs: 17.2 kB 1
FS2000/irf 1.07 k allocs: 0.0944 MB 1.14 k allocs: 0.102 MB 0.926
FS2000/jacobian 0.046 k allocs: 1.62 kB 0.046 k allocs: 1.62 kB 1
FS2000/lyapunov/bartels_stewart 0.065 k allocs: 0.0563 MB 0.065 k allocs: 0.0563 MB 1
FS2000/lyapunov/bicgstab 0.038 k allocs: 3.51 kB 0.038 k allocs: 3.51 kB 1
FS2000/lyapunov/doubling 30 allocs: 3.26 kB 30 allocs: 3.26 kB 1
FS2000/lyapunov/gmres 0.034 k allocs: 3.45 kB 0.034 k allocs: 3.45 kB 1
FS2000/qme/doubling 6 allocs: 1.7 kB 6 allocs: 1.7 kB 1
FS2000/qme/schur 9 allocs: 1.95 kB 9 allocs: 1.95 kB 1
NAWM_EAUS_2008/NSSS 0.588 k allocs: 0.604 MB 0.898 k allocs: 0.625 MB 0.966
NAWM_EAUS_2008/covariance 1.13 k allocs: 2.66 MB 1.44 k allocs: 2.68 MB 0.992
NAWM_EAUS_2008/irf 10.2 k allocs: 9.61 MB 11.6 k allocs: 9.77 MB 0.984
NAWM_EAUS_2008/jacobian 0.076 k allocs: 0.714 MB 0.076 k allocs: 0.714 MB 1
NAWM_EAUS_2008/lyapunov/bartels_stewart 0.187 k allocs: 3.5 MB 0.187 k allocs: 3.5 MB 1
NAWM_EAUS_2008/lyapunov/bicgstab 0.3 k allocs: 0.409 MB 0.274 k allocs: 0.408 MB 1
NAWM_EAUS_2008/lyapunov/doubling 0.034 k allocs: 0.404 MB 0.034 k allocs: 0.404 MB 1
NAWM_EAUS_2008/lyapunov/gmres 0.123 k allocs: 0.406 MB 0.123 k allocs: 0.406 MB 1
NAWM_EAUS_2008/qme/doubling 8 allocs: 0.362 MB 8 allocs: 0.362 MB 1
NAWM_EAUS_2008/qme/schur 12 allocs: 0.365 MB 12 allocs: 0.365 MB 1
Smets_Wouters_2007/NSSS 0.073 k allocs: 2.56 kB 0.148 k allocs: 3.8 kB 0.674
Smets_Wouters_2007/covariance 0.289 k allocs: 0.188 MB 0.365 k allocs: 0.189 MB 0.994
Smets_Wouters_2007/irf 3.36 k allocs: 0.918 MB 3.77 k allocs: 0.96 MB 0.956
Smets_Wouters_2007/jacobian 0.059 k allocs: 0.0636 MB 0.059 k allocs: 0.0636 MB 1
Smets_Wouters_2007/lyapunov/bartels_stewart 0.09 k allocs: 0.326 MB 0.09 k allocs: 0.326 MB 1
Smets_Wouters_2007/lyapunov/bicgstab 0.158 k allocs: 0.036 MB 0.152 k allocs: 0.0359 MB 1
Smets_Wouters_2007/lyapunov/doubling 0.034 k allocs: 0.034 MB 0.034 k allocs: 0.034 MB 1
Smets_Wouters_2007/lyapunov/gmres 0.098 k allocs: 0.0351 MB 0.098 k allocs: 0.0351 MB 1
Smets_Wouters_2007/qme/doubling 8 allocs: 0.0317 MB 8 allocs: 0.0317 MB 1
Smets_Wouters_2007/qme/schur 11 allocs: 0.0325 MB 11 allocs: 0.0325 MB 1
time_to_load 0.143 k allocs: 10.6 kB 0.143 k allocs: 10.6 kB 1

Benchmark Plots

A plot of the benchmark results have been uploaded as an artifact to the workflow run for this PR.
Go to "Actions"->"Benchmark a pull request"->[the most recent run]->"Artifacts" (at the bottom).

@codecov-commenter

codecov-commenter commented Jun 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.40884% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.32%. Comparing base (f2274a0) to head (3eed3ae).

Files with missing lines Patch % Lines
src/algorithms/sylvester.jl 37.50% 5 Missing ⚠️
src/algorithms/lyapunov.jl 50.00% 4 Missing ⚠️
src/MacroModelling.jl 90.00% 2 Missing ⚠️
src/rrules.jl 99.36% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #300      +/-   ##
==========================================
+ Coverage   88.05%   88.32%   +0.27%     
==========================================
  Files          35       35              
  Lines       30243    30510     +267     
==========================================
+ Hits        26629    26948     +319     
+ Misses       3614     3562      -52     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
@thorek1
thorek1 force-pushed the 3rd_order_pullback_improvements branch from dd784a5 to e1add5d Compare June 9, 2026 15:28
…rement_nested_initial_state_rdata!

Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Thore Kockerols and others added 9 commits June 12, 2026 10:32
The state_update in parse_algorithm_to_state_update was zeroing out the
constant column of S₁: [S₁[:,1:nPast] zeros(nVars) S₁[:,nPast+1:end]].
Since the augmented state includes 1 as the constant, this dropped the
constant contribution from the first-order term, breaking the SSS
fixed-point property (no-shock IRF would not stay at SSS).
thorek1 and others added 21 commits June 13, 2026 17:52
…ut_to_index

- Move normalize_superscript from StatsPlotsExt.jl to core module
- Sort shock_idx by normalized name inside parse_shocks_input_to_index
- Import normalize_superscript explicitly in StatsPlotsExt.jl
- All downstream callers (get_irf, plot_irf, plot_irf!, girf) now get
  consistently sorted shock order
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.

4 participants