Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use single LinearConstraintProjection in ProximalProjection #1409

Open
wants to merge 23 commits into
base: master
Choose a base branch
from

Conversation

YigitElma
Copy link
Collaborator

@YigitElma YigitElma commented Nov 27, 2024

  • Adds a _eq_solve_objective property to ProximalProjection which will be LinearConstraintProjection of ForceBalance and fixed boundary constraints.

  • Updates the fixed parameter constraint targets of _eq_solve_objective, and calculate particular solution without factorization

  • Passes _eq_solve_objective to eq.perturb and eq.solve

  • Updates proximal-... benchmarks to include solve and perturb part. Previously, force balance was not solved since the previous x value was used. I slightly change the x using random number to include that part too

Resolves #1404

@dpanici
Copy link
Collaborator

dpanici commented Nov 27, 2024

Add kwarg eq.solve which takes in LinearConstraintProjection called linear_constraint, which gets passed in through options of optimizer.optimize and from there it will skip necessary builds etc

Copy link
Contributor

github-actions bot commented Jan 30, 2025

|             benchmark_name             |         dt(%)          |         dt(s)          |        t_new(s)        |        t_old(s)        | 
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
 test_build_transform_fft_lowres         |     -0.24 +/- 1.22     | -1.25e-03 +/- 6.33e-03 |  5.19e-01 +/- 4.1e-03  |  5.21e-01 +/- 4.8e-03  |
 test_equilibrium_init_medres            |     +0.14 +/- 0.80     | +5.80e-03 +/- 3.26e-02 |  4.09e+00 +/- 2.4e-02  |  4.08e+00 +/- 2.2e-02  |
 test_equilibrium_init_highres           |     -0.37 +/- 0.93     | -1.98e-02 +/- 4.99e-02 |  5.34e+00 +/- 3.3e-02  |  5.36e+00 +/- 3.8e-02  |
 test_objective_compile_dshape_current   |     +0.18 +/- 4.38     | +7.16e-03 +/- 1.77e-01 |  4.05e+00 +/- 1.2e-01  |  4.04e+00 +/- 1.3e-01  |
 test_objective_compute_dshape_current   |     -0.15 +/- 1.10     | -7.68e-06 +/- 5.64e-05 |  5.11e-03 +/- 4.0e-05  |  5.12e-03 +/- 3.9e-05  |
 test_objective_jac_dshape_current       |     +0.76 +/- 7.32     | +3.19e-04 +/- 3.07e-03 |  4.23e-02 +/- 2.4e-03  |  4.20e-02 +/- 1.9e-03  |
 test_perturb_2                          |     +0.03 +/- 0.65     | +6.56e-03 +/- 1.26e-01 |  1.94e+01 +/- 1.1e-01  |  1.94e+01 +/- 5.8e-02  |
+test_proximal_jac_atf_with_eq_update    |     -6.04 +/- 0.90     | -2.65e+00 +/- 3.95e-01 |  4.12e+01 +/- 1.7e-01  |  4.39e+01 +/- 3.6e-01  |
 test_proximal_freeb_jac                 |     -0.73 +/- 1.54     | -5.38e-02 +/- 1.13e-01 |  7.29e+00 +/- 9.9e-02  |  7.35e+00 +/- 5.4e-02  |
 test_solve_fixed_iter_compiled          |     +0.49 +/- 2.45     | +9.77e-02 +/- 4.88e-01 |  2.01e+01 +/- 2.2e-01  |  2.00e+01 +/- 4.4e-01  |
 test_LinearConstraintProjection_build   |     +2.95 +/- 2.84     | +3.02e-01 +/- 2.90e-01 |  1.05e+01 +/- 2.8e-01  |  1.02e+01 +/- 6.5e-02  |
 test_build_transform_fft_midres         |     +3.72 +/- 3.09     | +2.36e-02 +/- 1.96e-02 |  6.57e-01 +/- 9.1e-03  |  6.33e-01 +/- 1.7e-02  |
 test_build_transform_fft_highres        |     +3.22 +/- 2.72     | +3.17e-02 +/- 2.68e-02 |  1.02e+00 +/- 1.5e-02  |  9.85e-01 +/- 2.2e-02  |
-test_equilibrium_init_lowres            |     +8.65 +/- 2.60     | +3.50e-01 +/- 1.05e-01 |  4.40e+00 +/- 4.9e-02  |  4.05e+00 +/- 9.3e-02  |
 test_objective_compile_atf              |     +3.80 +/- 2.80     | +3.25e-01 +/- 2.39e-01 |  8.87e+00 +/- 5.9e-02  |  8.54e+00 +/- 2.3e-01  |
 test_objective_compute_atf              |     +6.09 +/- 4.04     | +9.67e-04 +/- 6.41e-04 |  1.68e-02 +/- 3.0e-04  |  1.59e-02 +/- 5.7e-04  |
 test_objective_jac_atf                  |     +0.29 +/- 1.44     | +5.80e-03 +/- 2.86e-02 |  1.98e+00 +/- 1.7e-02  |  1.98e+00 +/- 2.3e-02  |
 test_perturb_1                          |     -4.12 +/- 3.48     | -6.70e-01 +/- 5.66e-01 |  1.56e+01 +/- 5.6e-01  |  1.63e+01 +/- 7.8e-02  |
+test_proximal_jac_atf                   |     -3.00 +/- 0.89     | -2.56e-01 +/- 7.57e-02 |  8.27e+00 +/- 5.2e-02  |  8.52e+00 +/- 5.5e-02  |
+test_proximal_freeb_compute             |    -48.76 +/- 1.22     | -9.92e-02 +/- 2.48e-03 |  1.04e-01 +/- 1.0e-03  |  2.03e-01 +/- 2.3e-03  |
+test_solve_fixed_iter                   |     -5.42 +/- 1.79     | -1.88e+00 +/- 6.21e-01 |  3.27e+01 +/- 5.1e-01  |  3.46e+01 +/- 3.5e-01  |

CHANGELOG.md Outdated Show resolved Hide resolved
@YigitElma YigitElma marked this pull request as ready for review January 31, 2025 06:42
Copy link

codecov bot commented Jan 31, 2025

Codecov Report

Attention: Patch coverage is 95.27027% with 7 lines in your changes missing coverage. Please review.

Project coverage is 95.68%. Comparing base (48eb4d0) to head (5b60d2b).
Report is 6 commits behind head on master.

Files with missing lines Patch % Lines
desc/optimize/optimizer.py 94.44% 3 Missing ⚠️
desc/equilibrium/equilibrium.py 80.00% 2 Missing ⚠️
desc/optimize/_constraint_wrappers.py 96.42% 1 Missing ⚠️
desc/perturbations.py 96.55% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1409      +/-   ##
==========================================
- Coverage   95.69%   95.68%   -0.01%     
==========================================
  Files         101      101              
  Lines       25633    25694      +61     
==========================================
+ Hits        24529    24585      +56     
- Misses       1104     1109       +5     
Files with missing lines Coverage Δ
desc/objectives/utils.py 100.00% <100.00%> (ø)
desc/vmec.py 91.91% <100.00%> (ø)
desc/optimize/_constraint_wrappers.py 97.12% <96.42%> (-0.11%) ⬇️
desc/perturbations.py 89.05% <96.55%> (+0.19%) ⬆️
desc/equilibrium/equilibrium.py 95.85% <80.00%> (-0.24%) ⬇️
desc/optimize/optimizer.py 96.83% <94.44%> (-0.30%) ⬇️

... and 1 file with indirect coverage changes

@YigitElma YigitElma requested review from a team and rahulgaur104 and removed request for a team January 31, 2025 22:06
desc/equilibrium/equilibrium.py Outdated Show resolved Hide resolved
desc/optimize/_constraint_wrappers.py Show resolved Hide resolved
if hasattr(con, "update_target"):
con.update_target(self._eq)
if (x != self._allx[-1]).all():
self._eq_solve_objective.update_constraint_target(self._eq)
Copy link
Member

Choose a reason for hiding this comment

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

i think this needs to be inside the else block above. if we reset the equilibrium we should reset the constraints as well

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not sure I understand the previous if statement completely. If store=True then we store the intermediate equilibrium in history, but if it is False, history only has the first params_dict, right? Why do we go back to the initial one?

desc/optimize/optimizer.py Outdated Show resolved Hide resolved
desc/perturbations.py Show resolved Hide resolved
desc/perturbations.py Outdated Show resolved Hide resolved
if linear_constraint is not None and nonlinear_constraint is not None:
objective, linear_constraint, nonlinear_constraint = combine_args(
objective, linear_constraint, nonlinear_constraint
if not is_linear_proj:
Copy link
Member

Choose a reason for hiding this comment

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

might be worth moving all the stuff in this block to a helper function rather than adding another level of conditionals ie

if not is_linear_proj:
    obj, cons = _helper_func_to_combine_objs_and_check_stuff(obj, cons)
else:
   nonlinear_constraint = None
   if not objective.built:
     objective.build(verbose=verbose)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not sure about how to proceed with x_scale? Do people use it often? The constraint updater I have just uses the D for scaling.


# since D has changed, we need to update the ADinv
self._ADinv = (1 / Dnew)[unfixed_idx, None] * self._Ainv
self._D = Dnew
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I also need to update the null space, like I did for Ainv. Previously, when I missed updating Ainv, test_bootstrap_consistency_current was failing.

@YigitElma
Copy link
Collaborator Author

|             benchmark_name             |         dt(%)          |         dt(s)          |        t_new(s)        |        t_old(s)        | 
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
 test_build_transform_fft_midres         |     +3.72 +/- 3.09     | +2.36e-02 +/- 1.96e-02 |  6.57e-01 +/- 9.1e-03  |  6.33e-01 +/- 1.7e-02  |
 test_build_transform_fft_highres        |     +3.22 +/- 2.72     | +3.17e-02 +/- 2.68e-02 |  1.02e+00 +/- 1.5e-02  |  9.85e-01 +/- 2.2e-02  |
-test_equilibrium_init_lowres            |     +8.65 +/- 2.60     | +3.50e-01 +/- 1.05e-01 |  4.40e+00 +/- 4.9e-02  |  4.05e+00 +/- 9.3e-02  |
 test_objective_compile_atf              |     +3.80 +/- 2.80     | +3.25e-01 +/- 2.39e-01 |  8.87e+00 +/- 5.9e-02  |  8.54e+00 +/- 2.3e-01  |
 test_objective_compute_atf              |     +6.09 +/- 4.04     | +9.67e-04 +/- 6.41e-04 |  1.68e-02 +/- 3.0e-04  |  1.59e-02 +/- 5.7e-04  |
 test_objective_jac_atf                  |     +0.29 +/- 1.44     | +5.80e-03 +/- 2.86e-02 |  1.98e+00 +/- 1.7e-02  |  1.98e+00 +/- 2.3e-02  |
 test_perturb_1                          |     -4.12 +/- 3.48     | -6.70e-01 +/- 5.66e-01 |  1.56e+01 +/- 5.6e-01  |  1.63e+01 +/- 7.8e-02  |
+test_proximal_jac_atf                   |     -3.00 +/- 0.89     | -2.56e-01 +/- 7.57e-02 |  8.27e+00 +/- 5.2e-02  |  8.52e+00 +/- 5.5e-02  |
+test_proximal_freeb_compute             |    -48.76 +/- 1.22     | -9.92e-02 +/- 2.48e-03 |  1.04e-01 +/- 1.0e-03  |  2.03e-01 +/- 2.3e-03  |
+test_solve_fixed_iter                   |     -5.42 +/- 1.79     | -1.88e+00 +/- 6.21e-01 |  3.27e+01 +/- 5.1e-01  |  3.46e+01 +/- 3.5e-01  |

Don't be misled by the 50% speed improvement in test_proximal_freeb_compute. It is because I made the constraint update part optional.

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.

Don't call factorize_linear_constraint every time in _update_equilibrium of ProximalProjection?
3 participants