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

Density Screening Refactor Part 1: test_erisieve.py Rework #2547

Merged
merged 19 commits into from
Jun 10, 2022

Conversation

davpoolechem
Copy link

@davpoolechem davpoolechem commented Apr 14, 2022

Description

This PR is the first in a series of planned PRs designed to remove density screening from the TwoBodyAOInt object and into the JK object. Having density screening available in TwoBodyAOInt runs the risk of applying density screening to algorithms where density screening doesn't make sense. Thus, it would be a good idea to move the logic of density screening to where it is more correctly applied, i.e., the JK object.

This PR solves two issues simultaneously:

  1. The primary purpose of this PR is to change the test_erisieve.py tests to work with the planned future density screening refactor. One issue that moving density screening from TwoBodyAOInt to JK currently brings up, is that it causes the tests on density screening within the pytest test_erisieve.py to fail. These failures occur because test_erisieve.py performs its screening tests directly using an ERI object generated by IntegralFactory. With density screening being removed from the TwoBodyAOInt object, this method of density screening testing can no longer be done. The current PR is designed to address this issue for when the density screening refactor happens. The aforementioned issue is addressed by implementing a new variable to the HF wavefunction, computed_shells_per_iter_, which keeps track of the number of shell quartets computed per SCF iteration. The computed_shells_per_iter_ variable is accessible to the user via Python, and thus can be used to conduct screening tests. In this way, density screening tests can be performed without the need for an ERI object.

  2. As a bonus from the changes introduced by this PR, the DirectJK algorithm no longer has a need to print computed shell quartet counts to bench.dat. Bench.dat is used exclusively by the DirectJK object to dump the number of shell quartets computed per SCF iteration somewhere. That data is now accessible to the user in a cleaner fashion - it can be accessed through Python, in a manipulatable format.

Notes

  1. Note that the changes in this PR have not been applied to the LinK portion of the DirectJK code. This is intentional, as Andy is planning on moving LinK out of DirectJK entirely, and editing the LinK code within DirectJK would interfere with that. Thus, the changes in this branch will be applied to LinK in a later update.

Todos

  • [ X ] Addition of computed_shells_ member to JK object, which keeps track of number of shells computed during the JK build process.
  • [ X ] Addition of computed_shells_per_iter_ member to HF wavefunction objects, which keep track of number of shells computed during each SCF iteration. This information can be accessed by the user via Python.
  • [ X ] Modification of density screening tests in test_erisieve.py using the above class changes to allow the tests to run without construction of an ERI object.

Questions

  • Currently, only the density screening tests in test_erisieve.py use the new computed_shells_per_iter_ framework to test screening. Other tests in test_erisieve.py perform their tests using a generated ERI object. Should use of computed_shells_per_iter_ comparisons be applied to other tests in test_erisieve.py, as well?

Checklist

Status

  • [ X ] Ready for review
  • Ready for merge

@JonathonMisiewicz
Copy link
Contributor

Details about how the integrals were computed should be the province of the JK object, not the HF wavefunction, so I disagree with creating this new variable as described.

Can we instead have computed_shells_per_iter_ on the JK object and query the JK object, after the HF, for test purposes?

@davpoolechem
Copy link
Author

Details about how the integrals were computed should be the province of the JK object, not the HF wavefunction, so I disagree with creating this new variable as described.

Can we instead have computed_shells_per_iter_ on the JK object and query the JK object, after the HF, for test purposes?

That should definitely be doable! Give me a bit, and that change can be made.

@davpoolechem
Copy link
Author

Done and done! computed_shells_per_iter_ is now in the JK object.

Copy link
Contributor

@JonathonMisiewicz JonathonMisiewicz left a comment

Choose a reason for hiding this comment

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

I have two minor code cleanup requests, but LGTM otherwise.

Short PRs are appreciated!

psi4/src/export_fock.cc Outdated Show resolved Hide resolved
psi4/src/psi4/libfock/jk.h Outdated Show resolved Hide resolved
@JonathonMisiewicz JonathonMisiewicz added this to the Psi4 1.7 milestone May 21, 2022
Copy link
Contributor

@jeffschriber jeffschriber left a comment

Choose a reason for hiding this comment

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

LGTM, no comments from me

Copy link
Contributor

@zachglick zachglick left a comment

Choose a reason for hiding this comment

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

Looks good

@@ -394,7 +394,9 @@ void export_wavefunction(py::module& m) {
"Are we to do excited-state MOM?")
.def_property("MOM_performed_", &scf::HF::MOM_performed, &scf::HF::set_MOM_performed,
"MOM performed current iteration?")
.def_property("attempt_number_", &scf::HF::attempt_number, &scf::HF::set_attempt_number,
.def_property("computed_shells_per_iter_", &scf::HF::computed_shells_per_iter, &scf::HF::set_computed_shells_per_iter,
"Array containing the number of shells computed (not screrened out) during each SCF iteration.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"Array containing the number of shells computed (not screrened out) during each SCF iteration.")
"Array containing the number of shell quartets computed (not screened out) during each SCF iteration.")

schwarz_computed_shells_expected = [20290, 20290, 20290, 20290, 20290, 20290, 20290, 20290, 20290]
density_computed_shells_expected = [13171, 19618, 19665, 19657, 19661, 19661, 19663, 19663, 19663]

for iter_ in range(0,9):
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to explicitly check that the lists of expected and computed shell quartets are the same length (the number of SCF iterations, which has been hardcoded as 9 here).

Better yet, I think there's a compare_arrays function that you could call instead of repeated calls to compare_integers.

Copy link
Member

Choose a reason for hiding this comment

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

good point. compare_arrays is legacy name -- you can use compare_values directly. It handles float-like, while compare handles int-like.

Copy link
Author

Choose a reason for hiding this comment

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

This is indeed a very good point. I will make these changes!

Copy link
Author

Choose a reason for hiding this comment

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

All right, this change should be made now!

assert compare_integers(screen_count_uhf, 19440, 'UHF Density Screened Ints Count, Cutoff 1.0e-12')
computed_shells_expected = [13171, 19618, 19665, 19657, 19661, 19661, 19663, 19663, 19663]

for iter_ in range(0,9):
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above comment

psi4/src/export_fock.cc Outdated Show resolved Hide resolved
psi4/src/psi4/libfock/jk.h Outdated Show resolved Hide resolved
psi4/src/psi4/libfock/jk.h Outdated Show resolved Hide resolved
psi4/src/psi4/libfock/jk.h Outdated Show resolved Hide resolved
psi4/src/psi4/libfock/jk.h Outdated Show resolved Hide resolved
psi4/src/psi4/libfock/jk.h Outdated Show resolved Hide resolved
psi4/src/psi4/libfock/DirectJK.cc Show resolved Hide resolved
tests/pytests/test_erisieve.py Show resolved Hide resolved
David Poole and others added 2 commits June 10, 2022 12:26
@davpoolechem
Copy link
Author

So I now realize something - we may want to apply some of the benchmarking changes made in this PR to DFJCOSK, as well. It will increase the size of the PR, but the benchmarking changes in this PR currently only extend to DirectJK at the moment. Since DFJCOSK has two methods that it separately benchmarks, it will require a bit of retooling regarding some of the internals of the benchmarking framework. It should not have a significant impact on test_erisieve, however.

Thoughts?

@loriab
Copy link
Member

loriab commented Jun 10, 2022

So I now realize something - we may want to apply some of the benchmarking changes made in this PR to DFJCOSK, as well. It will increase the size of the PR, but the benchmarking changes in this PR currently only extend to DirectJK at the moment. Since DFJCOSK has two methods that it separately benchmarks, it will require a bit of retooling regarding some of the internals of the benchmarking framework. It should not have a significant impact on test_erisieve, however.

Thoughts?

Unless the DFJCOSK changes would undo much of this PR, I think a follow-up PR would be best.

@davpoolechem
Copy link
Author

davpoolechem commented Jun 10, 2022

So I now realize something - we may want to apply some of the benchmarking changes made in this PR to DFJCOSK, as well. It will increase the size of the PR, but the benchmarking changes in this PR currently only extend to DirectJK at the moment. Since DFJCOSK has two methods that it separately benchmarks, it will require a bit of retooling regarding some of the internals of the benchmarking framework. It should not have a significant impact on test_erisieve, however.

Thoughts?

Unless the DFJCOSK changes would undo much of this PR, I think a follow-up PR would be best.

DFJCOSK won't explicitly undo most of this PR, nicely enough, though it will require some changes to how the computed_shells member functions/variables are handled. Regardless, it won't lead to significant changes in test_erisieve, so a separate PR should work fine. And ultimately, the big point of this PR is to allow testing of density screening in test_erisieve without needing to directly construct and use separate TwoBodyAOInt objects, since the plan is to remove density screening from TwoBodyAOInt entirely.

Thank you for your feedback!

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.

None yet

5 participants