Skip to content

Large cohort scaling improvements#2575

Open
akenmorris wants to merge 3 commits into
masterfrom
amorris/scaling_improvements
Open

Large cohort scaling improvements#2575
akenmorris wants to merge 3 commits into
masterfrom
amorris/scaling_improvements

Conversation

@akenmorris

Copy link
Copy Markdown
Contributor

Two changes to the per-iteration correspondence update in optimize: initialization stops multiplying by an N×N identity (an O(P·N²) no-op), and the optimization phase decomposes the symmetric Gram matrix with a symmetric eigensolver in Eigen instead of a single-threaded general SVD. Together they speed up both phases and restore multi-core use on large cohorts (about 3.5× end-to-end at N=1024, and 14× on the optimization phase at N=4096), with no change to the optimization result.

In mean-energy mode the inverse covariance is the identity, so the
gradient update is just the mean-centered points. The two correspondence
functions were still building an NxN identity and multiplying by it
(points_minus_mean * pinvMat) on every initialization iteration, which
is an O(P*N^2) no-op.

Drop the multiply in both the image/DT path (LegacyCorrespondenceFunction)
and the mesh/normals path (CorrespondenceFunction). The result is
identical, since multiplying by an exact identity changes nothing.
OptimizeTests passes.
The optimization phase decomposes the NxN Gram matrix Y^T Y on every
iteration. That matrix is symmetric positive-semidefinite, but the code
ran a general vnl_svd on it and did the surrounding matrix work in
single-threaded VNL.

Switch to Eigen::SelfAdjointEigenSolver in both entropy paths and keep
the Gram, inverse-covariance, and gradient products in Eigen. For an SPD
matrix the eigenvectors and eigenvalues are the SVD's U and singular
values, so the result matches to floating-point tolerance.
Reflect the mean-energy and eigensolver changes: both phases are faster
and multi-core again, so the single-core-at-scale description no longer
applied. Rewrite the prose, add before/after charts across the full grid
to N=4096 (runtime and CPU utilization) plus end-to-end run times, and
correct the per-phase core counts. Note that runtime is still cubic in
the number of shapes but with a smaller constant, and that optimization
utilization improves but still declines at the very high end because the
eigensolve itself stays serial. Remove the pre-improvement collapse charts.
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