Repository navigation
feat(librpa): add reader-v1 producer exports - #8053
AroundPeking wants to merge 37 commits into
Conversation
…der-v1-remote-update # Conflicts: # .readthedocs.yaml # docs/conf.py
…ssion Preserve velocity_matrix.txt, rename Vxc text output and references, reject unsupported reader-v1 symmetry, abort the producer communicator on output exceptions, and validate two-rank KS assembly against same-run text data. Drop unrelated RTD changes already in develop and remove unused gauge references.
The shared MPI input fixture enables symmetry=1, so select the legacy LibRPA output version and update the corresponding parser expectation. Keep reader-v1's symmetry=-1 check and the dedicated v1 producer cases. Validated on df_iopcas_ghj with OMP_NUM_THREADS=1: - GNU 12.3 Module_IO CTest group: 53/53 passed (ENABLE_LIBRI=OFF). - Intel-built reader-v1 producer CTests: 3/3 passed, including two ranks. - Cases 60 and 64: all 46 fixture files retain their SHA256 hashes. This changes test configuration only; no user-facing INPUT behavior or generated parameter documentation changes are required.
Critsium-xy
left a comment
There was a problem hiding this comment.
Follow-up review. The file-split itself looks right now: rpa_lri.hpp is gone, the 16 replacements are real compiled units (69-433 lines, all under 500), rpa_lri_detail.h is declaration-only with an #ifndef guard, both CMakeLists.txt and Makefile.Objects are updated, agent_governance_check.py reports no errors and code_quality_score.py passes every new module_ri file. Remaining findings inline. Not built or tested locally; the Test job is still pending on this head.
| this->out_bands(pelec); | ||
| this->out_eigen_vector(parav, psi); | ||
| this->out_struc(ucell); | ||
| this->out_bz_sampling(ucell); |
There was a problem hiding this comment.
out_bz_sampling runs for every out_librpa_ver, including the default 0, and the function itself has no version check. rpa_lri_bz.cpp:28 requires nk_full == nmp[0]*nmp[1]*nmp[2], but an explicit Direct/Cartesian/Line KPT list leaves nmp = {0,0,0} (only the MP branch writes it, klist.cpp:319). So a v0 run that worked before now throws and MPI_Aborts after SCF has already finished. Every existing rpa case uses Gamma plus symmetry -1, so CI does not cover this.
Please gate this call on out_librpa_ver == 1, and reject out_librpa_ver = 1 on a non-uniform grid in the INPUT check rather than aborting mid-run.
| // the operations in the input cell's fractional row-vector convention. | ||
| if (this->runtime.input.symmetry == "1" && this->runtime.input.nspin != 4) | ||
| { | ||
| RpaLriDetail::write_stru_sym(ofs, ucell, *p_kv); |
There was a problem hiding this comment.
The k-point block above is gated on out_librpa_ver != 1, but this symmetry block is gated only on symmetry == "1", so it also runs for v0. symmetry is reset to "1" by default for a non-gamma scf (read_inp_sys.cpp:290-307), so by default a v0 stru_out.txt gains a trailing block it never had. preserves_mesh additionally throws when nmp <= 0 (rpa_lri_sym.cpp:21), which is a second v0 abort path. Please move this into the v1 branch.
| } | ||
| ModuleBase::timer::end("RPA_LRI", "out_eigen_vector_v1_mpi_io"); | ||
| #endif | ||
| #ifndef __MPI |
There was a problem hiding this comment.
This serial writer can never be built. ENABLE_LIBRI is a cmake_dependent_option on ENABLE_LCAO;ENABLE_MPI (CMakeLists.txt:73-74), so these translation units are only ever compiled with __MPI defined and no build even syntax-checks these ~130 lines. Please drop them.
| const std::complex<double> zero(0.0, 0.0); | ||
| #ifdef __MPI | ||
| ModuleBase::timer::start("RPA_LRI", "out_eigen_vector_v1_mpi_io"); | ||
| try |
There was a problem hiding this comment.
try { opens inside this #ifdef __MPI, the guard closes at line 50, and a second #ifdef __MPI at line 51 continues the same function body and closes it with catch. It compiles, but this is the brace-across-guards pattern the previous review asked to remove. Use one guard for the whole block.
| const int npsin_tmp = this->runtime.input.nspin == 2 ? 2 : 1; | ||
| const int nbands = parav.get_wfc_global_nbands(); | ||
| const int nbasis = parav.get_wfc_global_nbasis(); | ||
| const std::complex<double> zero(0.0, 0.0); |
There was a problem hiding this comment.
zero is unused. Same in rpa_lri_eigenvector_v1.cpp:31-33, where nbands, nbasis and zero are all unused in the MPI build. Leftovers from the split; they produce compiler warnings.
| std::sort(blocks.begin(), blocks.end(), [](const V1Block& lhs, const V1Block& rhs) { | ||
| return lhs.pair_index < rhs.pair_index; | ||
| }); | ||
| if (blocks.empty()) |
There was a problem hiding this comment.
When a rank owns no block for this k point, no V_*_<ik>_r<rank>.dat is written at all. run_librpa_sym.py asserts the file exists for both ranks, so with more ranks or a sparser distribution this breaks. Either write a zero-block file, or document that readers must tolerate absent per-rank files.
| std::ofstream ofs; | ||
| const std::string out_name = (label == "") ? "out.dat" : label + "_out.dat"; | ||
| ofs.open(global_out_dir + term + "_" + out_name, | ||
| const std::string out_name = term == "vxc" |
There was a problem hiding this comment.
This renames an existing user-visible output (vxc_out.dat -> vxc.txt) and leaves a term == "vxc" special case inside a generic writer, while kinetic, vpp_local, vpp_nonlocal and vhartree keep <term>_out.dat. The PR body does not mention the break. Please rename the whole family in a separate PR, or at minimum document the breaking change here.
| wk[i] = wk_aux[k_index]; | ||
| isk[i] = isk_aux[k_index]; | ||
| } | ||
| kvec_c_full.resize(kvec_c_full_aux.size() / 3); |
There was a problem hiding this comment.
This changes shared k-point semantics beyond LibRPA: kvec_c_full is now the global full mesh on every rank instead of a pool-local slice, and ibz_index is no longer overwritten by the identity map after reduction (klist.cpp:89). That also fixes a real out-of-bounds read in ewald_vq.hpp:121, which indexes kvec_c_full up to nkstot_nospin. Please state this in the PR body: it affects EXX and has no EXX-side test.
| @@ -0,0 +1,6 @@ | |||
| etotref -34.21719023095261 | |||
| etotperatomref -17.1085951155 | |||
| CompareVXC_pass 0 | |||
There was a problem hiding this comment.
catch_properties.sh:409 now skips the whole has_xc block when LIBRPA_PRODUCER_CONTRACT=1, so CompareVXC_pass and CompareOrbXC_pass never reach result.out. check_out iterates over the keys present in result.out, so these two lines are silently ignored. Remove them, or keep the comparison. Same in 64_LIBRPA_NSPIN2/result.ref.
| COMMAND ${Python3_EXECUTABLE} ${ABACUS_TEST_DIR}/integrate/tools/run_librpa_sym.py | ||
| --abacus ${ABACUS_BIN_PATH} --cases ${ABACUS_TEST_DIR}/08_RI | ||
| ) | ||
| set_tests_properties(08_RI_librpa_symmetry PROPERTIES PROCESSORS 2 TIMEOUT 900) |
There was a problem hiding this comment.
run_librpa_sym.py performs 12 two-rank runs with timeout=120 each (run_librpa_sym.py:106-107), so the worst case exceeds this 900 s budget. Both new runners also hardcode mpirun, while the rest of the suite goes through Autotest.sh and the CMake MPI discovery.
Critsium-xy
left a comment
There was a problem hiding this comment.
Re-review of da7d65329. Findings 1-9, 12 and 13 from the previous round are resolved. One blocking regression in the new INPUT guard is inline below; it is what the failing Test job is reporting.
Two earlier points are still open, both in the PR description:
- The
vxc_out.dat->vxc.txtrename is a user-visible break and is not mentioned, andwrite_orb_energystill carries theterm == "vxc"special case while the other terms keep<term>_out.dat. - The k-point changes are not mentioned either:
kvec_c_fullis now the global full mesh on every rank andibz_indexis no longer overwritten by the identity map after reduction, which also fixes an out-of-bounds read inewald_vq.hpp:121. This affects EXX and has no EXX-side test.
Also: the summary still names the parameter out_librpa_reader_version instead of out_librpa_ver, and does not state the new hard requirement that out_librpa_ver = 1 needs a uniform Monkhorst-Pack grid.
Minor: esolver_fp.cpp drops from 58 to 56 in code_quality_score.py (already under the 60 line before this PR). Extracting the guard into a helper would keep LibRPA-specific validation out of the generic FP entry point.
Not built or run locally; based on static review plus the CI Test job log (run 37887346672).
| const double kspacing[3] = {this->inp_->kspacing[0], this->inp_->kspacing[1], this->inp_->kspacing[2]}; | ||
| const double koffset[3] = {this->inp_->koffset[0], this->inp_->koffset[1], this->inp_->koffset[2]}; | ||
| this->kv.set(ucell, ucell.symm, inp.kpoint_file, inp.nspin, ucell.G, ucell.latvec, GlobalV::ofs_running, GlobalV::ofs_warning, use_ibz, global_out_dir, gamma_only_local, kspacing, this->inp_->kmesh_type, koffset); | ||
| if (inp.rpa && inp.out_librpa_ver == 1) |
There was a problem hiding this comment.
get_is_mp() is only valid on rank 0, so this guard fires on every other rank.
is_mp is set in read_mp_mesh (klist.cpp:303,309), but read_kpoints returns immediately for my_rank != 0 (klist.cpp:218), and mpi_k() broadcasts nkstot, nkstot_nospin, nmp and koffset but not is_mp (klist.cpp:600-615). Every pre-existing get_is_mp() caller sits inside reduce_by_symmetry, which is itself rank-0 only, so the value never needed broadcasting; this is the first all-ranks consumer.
Result: rank 0 passes, every rank >= 1 hits WARNING_QUIT -> QUIT(1) -> exit(1), so any out_librpa_ver = 1 run on 2 or more ranks dies before SCF. The CI Test job confirms it: 08_RI_librpa_producer (-n 1) passes, while 08_RI_librpa_producer_mpi and 08_RI_librpa_symmetry fail with Process name: [[63785,1],1] / Exit code: 1 right after rank 0 prints DONE : INIT K-POINTS. Non-root stdout is suppressed, so the message is invisible.
Two possible fixes: drop get_is_mp() from the condition - nmp is written only on the MP path and is broadcast, so nmp[d] > 0 && prod(nmp) == nkstot_nospin is equivalent and rank-safe - or add Parallel_Common::bcast_bool(this->is_mp) in K_Vectors::mpi_k.
Summary
OUT.librpa.out_librpa_reader_versionand document the reader-v1 output protocol.nspin = 2cases.