Repository navigation
PySCFTheory: fix broken-symmetry SCF on GPU - #528
Merged
Merged
Conversation
run_BS_SCF changed the spin on self.mol, but on GPU mf.to_gpu() deep-copies the Mole, so the SCF (which uses self.mf.mol) never saw it: the "high-spin" step ran at the initial spin. Set the spin on self.mf.mol as well (set_BS_spin). The flipped density was passed as a list [dma, dmb]; gpu4pyscf's cupy.asarray(dm0) cannot convert a list of cupy arrays (AssertionError). Pass a single (2,nao,nao) array (cupy.stack on GPU, np.array on CPU). Adds a CPU test of the BS procedure (Li2 at 6 A, UHF), including a case where mf has its own copy of the Mole as after to_gpu(). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Owner
|
Good catch, indeed this was never tested on the GPU |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two bugs in
PySCFTheory.run_BS_SCF(BS=True) make the broken-symmetry procedure fail withplatform="GPU". Neither appears on CPU, which is probably why they went unnoticed.1. The spin change never reaches the SCF.
run_BS_SCFsetsself.mol.spinbefore the high-spin and the BS steps. On GPU,prepare_rundoesself.mf = self.mf.to_gpu(), which deep-copies theMole. The SCF then usesself.mf.mol, which keeps the spin it was built with. So the "high-spin" step silently runs at the target (BS) spin, from scratch. In our [4Fe-4S] case (HSmult 19) it ran at Ms = 0 with ⟨S²⟩ = 0 and diverged. Fix: a small helper,set_BS_spin, that sets the spin onself.moland, when it is a different object, onself.mf.mol.2. The flipped density is passed as a Python list. After the α/β swap,
dm = [dma, dmb]goes tomf.run(dm). On GPU,dma/dmbare cupy arrays, and gpu4pyscf callscupy.asarray(dm0), which cannot build an array from a list of cupy arrays and raisesAssertionError(cupy 14.2). Fix: pass one(2, nao, nao)array,cupy.stack([dma, dmb])on GPU andnp.array([dma, dmb])on CPU.Changes
ash/interfaces/interface_pyscf.py:set_BS_spinhelper, used for both spin changes inrun_BS_SCF; stacked initial density (+16/−3).ash/tests/test_pyscf_broken_symmetry.py(new, CPU only, about 1 s): BS on Li2 stretched to 6 Å (UHF/def2-SVP, HSmult 3, flip atom 1). It checks the spin the SCF actually uses at each step (2, then 0), that the BS step gets a single array, and that ⟨S²⟩ ≈ 1. A second case copies theMoleintomf, the wayto_gpu()does, so the GPU failure is covered without a GPU.Testing
[0, 0]instead of[2, 0]; list passed to the SCF) and pass with this PR.test_pyscf_scf_convergence.pystill passes.PySCFTheory(platform="GPU", BS=True, ...):mf.mol.spin, ⟨S²⟩AssertionErrorincupy.asarrayndarraypassedNote for the test molecule: H2 can't be used on GPU. Its triplet has no β electrons, and gpu4pyscf's
get_occlogging then fails (TypeError: must be real number, not NoneType). That's why the test uses Li2.🤖 Generated with Claude Code