-
Notifications
You must be signed in to change notification settings - Fork 61
Weighted poisson integration #872
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
base: master
Are you sure you want to change the base?
Conversation
69c9e20 to
3c67197
Compare
3c67197 to
d63167b
Compare
8273c3f to
817a80e
Compare
165ec32 to
252a3d0
Compare
| -2.00000000000000e-01 1.40000000000000e+00 7.70437678236428e-02 | ||
| -2.00000000000000e-01 1.45000000000000e+00 7.69776442679124e-02 | ||
| -2.00000000000000e-01 1.50000000000000e+00 7.69557395004421e-02 | ||
| -2.00000000000000e-01 -5.00000000000000e-01 5.66747557569237e-02 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are the test data changed here? I know this PR fixes the boundary condition in the integrator but 018_pathCV does not use any periodic CVs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix applies to Neumann (non-periodic) boundary conditions.
| width 0.2 | ||
| lowerBoundary 1.0 | ||
| upperBoundary 5.0 | ||
| upperBoundary 6.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the upper boundary changed in the test here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ensures that the custom grid has a different number of points than the default one based on the colvar's parameters. Because there was an accidental match in the previous test, some errors went unnoticed.
| bool colvarproxy_stub::total_forces_same_step() const | ||
| { | ||
| return total_force_requested; | ||
| return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this changed? Should it be also applied to the GPU test interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so, but @giacomofiorin may have a different opinion. I didn't see a rationale for that flag changing based on total_force_requested, i.e. the fact that it's true does not indicate that total forces are enabled or requested or even available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really have an opinion here, and certainly I wouldn't have a strong opinion on total-forces features. As a matter of fact, I even suggested to remove the code path associated with the "same step" feature.
#887 (comment)
src/colvargrid_integrate.h
Outdated
| bool weighted = false; | ||
| bool precompute = true; | ||
|
|
||
| colvar_grid_scalar* computation_grid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to use shared_ptr instead of a raw pointer, you can inherit this class from std::enable_shared_from_this. Also, if you want to keep the raw pointer, it should be initialized as nullptr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, since this is not managing any memory, we'll keep the raw pointer for simplicity but initialize to nullptr.
src/colvargrid_integrate.cpp
Outdated
|
|
||
| // Helper function to print vector<int> | ||
| std::string vec_to_string(const std::vector<int> &vec) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helper function is defined in the global namespace, and only used when debugging. It may cause linking errors if downstream MD engines have a function with the same name, so I think either it should be commented out, or put in the colvarmodule or a separate namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, this is a leftover from debugging, removing.
| gradients->incr(ix)) { | ||
| size_t count = gradients->samples->value(ix); | ||
| if (count > 0) { | ||
| insert_into_sorted_list<size_t>(sorted_counts, count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with the algorithm details, but random insertion in a vector should be quite slow. Why not just push_back and then std::sort?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, thanks!
| coefficient += regularized_weights[gradients->address(weight_coordinate)]; | ||
| } | ||
| coefficient *= weight_counts[i]; | ||
| laplacian_coefficients[computation_grid->address(ix) * multiplicity + i] += coefficient; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to pre-calculate the computation_grid->address(ix) * multiplicity in the outer loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm suggesting that Kevin-Lâm tries it, but my recent experience is that current compilers already optimize the hell out of everything, so there might be nothing to gain.
src/colvargrid_integrate.cpp
Outdated
| std::vector<int> zero_vector(nd, 0); | ||
| gradients_to_average_relative_positions.push_back(zero_vector); | ||
| } else { | ||
| for (int i = 0; i < pow(2, directions_to_average_along.size()); i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each time when comparing i with the end of loop, it has to recalculate pow, which might be slow. Is it possible to cache the index of the end of loop? Also, you should consider using cvm::integer_power.
|
When restarting |
src/colvargrid_integrate.cpp
Outdated
| cvm::real weight = regularized_weights[gradients->address(surrounding_point_coordinates)]; | ||
|
|
||
| for (size_t i = 0; i < nd; i++) { | ||
| div_at_point += pow(-1, surrounding_point_relative_position[i] + 1) * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(-1)^n could be either -1 or 1 depending on whether n is an even number or an odd number, so this can be simply calculated without calling pow.
src/colvargrid_integrate.cpp
Outdated
| { | ||
| const size_t linear_index = computation_grid->address(ix0); | ||
| cvm::real div_at_point = 0; | ||
| for (std::vector<int> surrounding_point_relative_position : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to use const std::vector<int>&.
| surrounding_points_relative_positions.clear(); | ||
| size_t n_combinations = pow(2, nd); | ||
| for (size_t i = 0; i < n_combinations; i++) { | ||
| surrounding_points_relative_positions.push_back(convert_base_two(i, nd)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel that the calls to convert_base_two is unnecessary because an integer has already all its bits itself. convert_base_two simply checks the bits of i and stores them into a vector of nd size. But maybe I am wrong, and I am not sure how to optimize this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not performance-critical, and this form is more legible than a bunch of (n >>i)&1 throughout the code.
in proxy_stubs wrt other proxys
uses CLI11.hpp, now we need to find a common place in the tree to share it with other tools also fixes Doxygen comments are noted by Haochuan
7f3e54a to
24f4098
Compare
Thanks Haochuan for the feedback.
Could you tell me exactly how you got this ? Is it running on local ? Because on git all the tests pass. |
Yes, I ran the code locally. The Github CI test should fail on the crash but I don't know why it didn't. As you can see in https://github.com/Colvars/colvars/actions/runs/20366808773/job/58523739156?pr=872#step:15:109, NAMD indeed crashed. |
Ok, thank you ! it should be fixed now. I had already spotted the bug and fixed it but in another branch (that you may review soon too)... |
Fix the compilation error of comparing signed and unsigned integers.
Implements weighted Poisson integration of free energy gradients.
Also fixes a small error in Neumann boundary conditions for the existing unweighted case.
TODO: