Skip to content

Move HSolverPW_SDFT into module_stodft as StoHSolverPW; rename HamiltSdftPW to StoHamiltPW - #8012

Merged
mohanchen merged 5 commits into
deepmodeling:developfrom
Critsium-xy:refactor/move-sdft-hsolver-to-stodft
Sep 27, 2026
Merged

mohanchen merged 5 commits into
deepmodeling:developfrom
Critsium-xy:refactor/move-sdft-hsolver-to-stodft

Conversation

@Critsium-xy

@Critsium-xy Critsium-xy commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Reminder

  • I have read AGENTS.md and docs/developers_guide/agent_governance.md.
  • I have linked an issue or explained why this PR does not need one.
  • I have added adequate unit tests and/or case tests, or explained why not.
  • I have listed the exact verification commands run and their results.
  • I have described user-visible behavior changes, including INPUT parameter changes.
  • I have explained core-module impact for ESolver, HSolver, ElecState, Hamilt, Operator, Psi, or other source/ changes.
  • I have requested any needed governance exception below.

Linked Issue

No issue. Follow-up to #7920, #7948 and #7974, and the last step of getting
source_hsolver down to a self-contained numerical module. No behaviour change.

Unit Tests and/or Case Tests for my changes

The PR has five commits:

commit content
1c06770af move HSolverPW_SDFT into module_stodft (as hsolver::HSolverSdftPW)
0068fe86b rename hamilt_sdft_pw / hamilt::HamiltSdftPW → sto_hamilt_pw / StoHamiltPW
1211e050e rename hsolver_sdft_pw / hsolver::HSolverSdftPW → sto_hsolver_pw / StoHSolverPW
b150bda01 fix: qualify hamilt::HamiltPW in the StoHamiltPW mock constructor of test_sto_tool.cpp
567b40e97 fix: build module_stodft/test without __CUDA/__ROCM, as source_hsolver/test does

CI on 567b40e97: all 17 checks pass, including every build configuration
(GNU, Intel, CUDA, Makefile & Intel, without ELPA / LCAO / MPI), Test,
Test on CUDA Build, abacuslite, PyTest and Governance checks. In Test:

 7/14 Test #212: MODULE_PW_Sto_Tool_UTs ............   Passed    0.01 sec
 8/14 Test #213: MODULE_PW_Sto_Hamilt_UTs ..........   Passed    0.01 sec
 9/14 Test #214: MODULE_PW_Sto_HSolver_UTs .........   Passed    0.32 sec
100% tests passed, 0 tests failed out of 14          (ctest -R MODULE_PW)
1/1 Test #422: 06_SDFT ..........................   Passed   22.33 sec

Every other ctest -R group in that job also reports 100% passed.

Commands run on 1c06770af (Linux, gcc, cmake 3.31 + ninja, 15 cores). Base
commit 4f2a39783 and that commit were built and tested in the same build tree.

cmake -B build -G Ninja -DBUILD_TESTING=ON -DENABLE_LCAO=ON -DENABLE_MPI=ON \
      -DENABLE_OPENMP=ON -DENABLE_ELPA=ON
cmake --build build -j15 -- -k 0
OMP_NUM_THREADS=1 ctest --test-dir build -E '^(0[1-9]|1[0-9])_'
python tools/03_code_analysis/agent_governance_check.py --staged

Result summary

check base 4f2a39783 1c06770af
full build, ELPA on 3436/3436, 0 errors reconfigure + 22/22 rebuilt, 0 errors
unit tests 92% passed, 29 failed of 364 92% passed, 29 failed of 364
governance check — 0 blockers

Failing sets are identical test-for-test (diff of the sorted lists is
empty) and are this sandbox's pre-existing failures. The total stays at 364, so
the moved test is still registered — it runs and passes under both names:

base    258/364 Test #258: MODULE_HSOLVER_sdft ............ Passed  1.12 sec
branch  204/364 Test #204: MODULE_PW_Sto_HSolver_UTs ...... Passed  1.11 sec

SDFT integration cases. A move of SDFT code deserves numerical evidence, so
I ran a spread of tests/06_SDFT against their committed result.ref:

case exercises branch etot (eV) result.ref Δ
01_PW_SDFT_10S_M plain SDFT -3951.2630794784217869 -3951.2630794784240607 2e-12
04_PW_SDFT_ALL all-stochastic -227.9078754578098085 -227.9078754578100074 2e-13
08_PW_BNDKPAR_SDFT_ALL band + k parallel -82.7617694001712891 -82.7617694001712749 1e-14
12_PW_BPCG_SDFT_5D11S bpcg -323.2802970208462625 -323.28029702 at ref precision

All reproduce their reference at machine precision. 08_PW_BNDKPAR_SDFT_ALL
matters in particular: it is the one that drives the BP_WORLD MPI_Bcast
inside the moved file.

Each run's own timing table confirms the moved class is what executed (these
runs predate the last rename, so the label is still HSolverSdftPW; from
1211e050e on it reads StoHSolverPW):

01_PW_SDFT_10S_M         HSolverSdftPW solve  1.16  6 calls  93.23%
04_PW_SDFT_ALL           HSolverSdftPW solve  1.29  3 calls  94.74%
08_PW_BNDKPAR_SDFT_ALL   HSolverSdftPW solve  0.26  7 calls  78.05%
12_PW_BPCG_SDFT_5D11S    HSolverSdftPW solve  0.91  4 calls  90.32%

Commands run locally on 1211e050e (the two rename commits):

python tools/03_code_analysis/agent_governance_check.py --base 4f2a39783 --head HEAD --format text
git grep -n "HamiltSdftPW\|HSolverSdftPW\|hamilt_sdft_pw\|hsolver_sdft_pw" -- source
  • governance check: 0 blockers, 14 warnings (listed under Governance Notes).
  • git grep: no remaining references to the old names.

Checks not run, with reason

  • Commits after 1c06770af were not built or tested locally — no build
    environment on the machine they were written on. CI is the verification for
    them (see above). The first CI run on 1211e050e caught two problems, both
    fixed in follow-up commits: an unqualified HamiltPW in a test mock that had
    relied on the old hamilt namespace (b150bda01), and the CUDA link failure
    described under "The unit test moves with the code" (567b40e97). The
    SDFT integration numbers above were not re-run locally after the renames; CI's
    06_SDFT group passes on 567b40e97.
  • The Makefile build path (Makefile.Objects is edited here): not built locally;
    CI's "Build with Makefile & Intel compilers" job covers it. The edits move one
    object entry from OBJS_HSOLVER to OBJS_SRCPW beside the other sto_*.o
    and rename two entries in place; the directory is already on the Makefile's
    search path.
  • GPU: no GPU runtime available to me. Nothing in this PR is device-specific —
    it is a file move plus renames — and CI's CUDA job compiles it.

What's changed?

#7974 inverted the hamilt/hsolver dependency through the HSOperator/HSMatrix
interfaces. After it, HSolverPW_SDFT was the only thing left in
source_hsolver reaching into source_hamilt, and the only thing left reaching
into source_pw
— and it was also what closed the one real include cycle in
this area:

source_pw/module_stodft/sto_elecond.h
  -> source_hsolver/hsolver_pw_sdft.h
       -> source_pw/module_stodft/hamilt_sdft_pw.h
       -> source_pw/module_stodft/sto_iter.h

It is not a solver algorithm. It owns a Stochastic_Iter, takes the SDFT
Hamiltonian, and orchestrates one stochastic-DFT SCF step. So this PR moves it
into module_stodft where the rest of SDFT lives.

Converting it to the HSOperator interface instead — the obvious alternative —
would have removed the source_hamilt include but left both source_pw edges
and the cycle intact. Moving it removes all three.

Rename. module_stodft names its files sto_* and keeps its classes
(StoChe, Sto_DOS, Sto_EleCond, Stochastic_Iter, Stochastic_WF, …) in
the global namespace. The moved class follows that convention, and so does the
SDFT Hamiltonian, whose hamilt_sdft_pw.h was the one file in the directory
still named after the layout it was originally moved in from:

hamilt_sdft_pw.{h,cpp}   hamilt::HamiltSdftPW    ->  sto_hamilt_pw.{h,cpp}   StoHamiltPW  : public hamilt::HamiltPW<T, Device>
hsolver_pw_sdft.{h,cpp}  hsolver::HSolverPW_SDFT ->  sto_hsolver_pw.{h,cpp}  StoHSolverPW : public hsolver::HSolverPW<T, Device>
  • Plain CamelCase StoXxxPW (as StoChe), rather than the underscore-mixed
    Sto_Xxx_PW spelling, and the basis suffix last (as sto_stress_pw).
  • Both classes leave their hamilt / hsolver namespaces, matching every
    other class in the directory; the Sto prefix does the disambiguating. Names
    that were previously found through the enclosing namespace are now qualified:
    the two base classes, hamilt::Operator and hamilt::hpsi_norm_op.
    kernels/hpsi_norm_op itself stays in namespace hamilt, like the other op
    kernels.
  • Unit test files follow the sources: test_sto_hamilt_pw.cpp,
    test_sto_hsolver_pw.cpp. The hsolver:: mocks inside the latter stay in
    namespace hsolver, since they mock the base-class side.

Result, measured over the non-test sources:

before after
source_hsolver → source_hamilt 1 file 0
source_hsolver → source_pw 2 files 0

The cycle is gone. What is left between the two modules is source_pw →
source_hsolver (hsolver_pw.h and para_lin_tf.h), which is the correct
direction. source_hsolver's remaining outward includes are source_base 134,
itself 42, source_estate 13, source_psi 9, source_basis 9, source_io 1,
source_cell 1.

The unit test moves with the code. Two wrinkles worth calling out:

  • module_stodft/test does abacus_disable_feature_definitions(__MPI), but this
    test calls MPI_Init in main() and its mocks take MPI_Comm arguments
    outside any #ifdef, so it keeps the definition via
    KEEP_FEATURE_DEFINITIONS __MPI — the same escape hatch
    MODULE_RELAX_socket_driver_test and the DFT+U tests use.
  • source_hsolver/test builds without __CUDA/__ROCM; module_stodft/test
    did not. With the definitions on, the CUDA build compiled the DEVICE_GPU
    instantiations of StoHSolverPW, HSolverPW and FFT_CUDA into the test
    without linking their GPU implementations, and the link failed. So
    module_stodft/test now disables both, like source_hsolver/test does. The
    directory's other two tests (Sto_Tool, Sto_Hamilt) exercise CPU code only;
    for them this just drops GPU template instantiations they never call.
    (__EXX, also disabled in source_hsolver/test, is not referenced by any
    source these tests compile, so it is left alone.)
  • Its two mock headers (hsolver_pw_sup.h, hsolver_supplementary_mock.h) are
    shared with MODULE_HSOLVER_pw, so they stay in source_hsolver/test/ and the
    moved test includes them by full path.

Governance Notes

  • INPUT/docs changes: none, and none needed. No Input_Item, no INPUT
    parameter, no output file format; the renamed classes are internal and not
    referenced from docs/.
  • User-visible changes: two, both cosmetic.
    1. The ModuleBase::TITLE/timer labels in the timing table of
      OUT.*/running_*.log follow the classes: HSolverPW_SDFT → StoHSolverPW
      and HamiltSdftPW → StoHamiltPW. Nothing in tests/ or any result.ref
      records them.
    2. The CTest target is renamed MODULE_HSOLVER_sdft →
      MODULE_PW_Sto_HSolver_UTs, so it groups with the module it now belongs to
      and with its two neighbours MODULE_PW_Sto_Tool_UTs and
      MODULE_PW_Sto_Hamilt_UTs. ctest -R MODULE_HSOLVER no longer selects it;
      ctest -R MODULE_PW does.
  • Core module impact: HSolver, Hamilt and ESolver. Pure move and rename — no
    logic, no signature and no arithmetic is touched. esolver_sdft_pw.cpp gains
    an explicit include of the solver header it was previously getting
    transitively through sto_elecond.h. Users of the SDFT Hamiltonian
    (esolver_sdft_pw, sto_dos, sto_elecond, sto_iter, sto_tool and their
    tests) only change the spelled type name.
  • Build wiring: module_stodft/test/CMakeLists.txt additionally disables
    __CUDA/__ROCM (see above). hsolver_pw_sdft.cpp moves from source_hsolver/CMakeLists.txt
    to module_stodft's hamilt_stodft_srcs as sto_hsolver_pw.cpp, and in
    Makefile.Objects from OBJS_HSOLVER to OBJS_SRCPW next to the other
    sto_*.o. hamilt_sdft_pw.cpp / .o is renamed in place in both.
  • Exceptions requested: none. Expected warnings:
    • Global dependency budget on five esolver_sdft_pw.cpp lines. These are
      the existing PARAM.globalv.* / GlobalV::ofs_running arguments of the
      StoHamiltPW and StoHSolverPW constructor calls and the solve call,
      re-indented because the type and object names got shorter. The check itself
      reports added=5, removed=5, net_delta=0.
    • Header dependency review on eight include lines. Each one swaps an existing
      include for the renamed path (sto_hamilt_pw.h in esolver_sdft_pw.h,
      sto_dos.h, sto_iter.h, sto_tool.h; sto_hsolver_pw.h in
      sto_elecond.h), or is one of the three includes of the moved
      sto_hsolver_pw.h, which the check sees as new because the file is new.
      Those point at the same headers as before; hsolver_pw.h becomes a full
      path now that it is no longer a sibling. No header gains a new dependency.
    • Documentation sync review: see "INPUT/docs changes" above.

🤖 Generated with Claude Code

After deepmodeling#7974 inverted the hamilt/hsolver dependency through the
HSOperator/HSMatrix interfaces, HSolverPW_SDFT was the only thing left in
source_hsolver still reaching into source_hamilt, and the only thing left
reaching into source_pw. It also closed the one real include cycle in the
area:

    sto_elecond.h -> source_hsolver/hsolver_pw_sdft.h
                  -> source_pw/module_stodft/{hamilt_sdft_pw.h, sto_iter.h}

It is not a solver algorithm: it owns a Stochastic_Iter, takes a
HamiltSdftPW*, and orchestrates the stochastic-DFT SCF step. It belongs in
module_stodft, so move it there. Converting it to HSOperator instead would
have dropped the hamilt include but left the source_pw edges and the cycle.

Renamed to match the sibling it now sits next to, which is the same class
of thing for the Hamiltonian side:

    hamilt_sdft_pw.h  -> hamilt::HamiltSdftPW  : public HamiltPW
    hsolver_sdft_pw.h -> hsolver::HSolverSdftPW : public HSolverPW

That also drops the CamelCase/SCREAMING_SNAKE mix in HSolverPW_SDFT and
puts the basis suffix last, as every other name in that directory does. The
namespace stays hsolver: the class implements the HSolver role, and the
directory already holds hamilt::HamiltSdftPW, so "namespace = role,
directory = feature area" is the established rule here.

Result, measured on the non-test sources:

    source_hsolver -> source_hamilt   1 file -> 0
    source_hsolver -> source_pw       2 files -> 0

The cycle is gone. What remains between the two is source_pw ->
source_hsolver (hsolver_pw.h, para_lin_tf.h), which is the correct
direction.

The unit test moves with the code and keeps __MPI via
KEEP_FEATURE_DEFINITIONS, because module_stodft/test disables it and this
test calls MPI_Init and has mocks taking MPI_Comm unconditionally. Its
CTest target is renamed MODULE_HSOLVER_sdft -> MODULE_PW_Sto_HSolver_UTs so
it groups with its new module and its two neighbours.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mohanchen mohanchen added Refactor Refactor ABACUS codes The Absolute Zero Reduce the "entropy" of the code to 0 labels Sep 24, 2026
Critsium-xy and others added 2 commits September 25, 2026 12:02
module_stodft names its files sto_* and keeps its classes (StoChe,
Sto_DOS, Stochastic_Iter, ...) in the global namespace.
hamilt_sdft_pw.{h,cpp} is the leftover from when this code lived under
hamilt_stodft, so bring it in line:

  hamilt_sdft_pw.{h,cpp}  -> sto_hamilt_pw.{h,cpp}
  hamilt::HamiltSdftPW    -> StoHamiltPW (global namespace)
  test_hamilt_sto.cpp     -> test_sto_hamilt_pw.cpp

Names that were found through the enclosing namespace (HamiltPW,
Operator, hpsi_norm_op) are now qualified with hamilt::. The timer and
classname labels follow the class name. No logic change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lver

Same treatment as StoHamiltPW in the previous commit, so both classes
this PR brings into module_stodft follow the directory's sto_* file
naming and global-namespace convention:

  hsolver_sdft_pw.{h,cpp}   -> sto_hsolver_pw.{h,cpp}
  hsolver::HSolverSdftPW    -> StoHSolverPW (global namespace)
  test_hsolver_sdft_pw.cpp  -> test_sto_hsolver_pw.cpp

The base class is now spelled hsolver::HSolverPW. The TITLE/timer
labels and the local object in ESolver_SDFT_PW follow the class name.
The test's hsolver:: mocks stay in namespace hsolver since they mock
the base-class side. No logic change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Critsium-xy Critsium-xy changed the title Move HSolverPW_SDFT into module_stodft as HSolverSdftPW Move HSolverPW_SDFT into module_stodft as StoHSolverPW; rename HamiltSdftPW to StoHamiltPW Sep 25, 2026
Critsium-xy and others added 2 commits September 27, 2026 18:31
The mock constructor's initializer list named the base as HamiltPW,
which was only found while the class lived in namespace hamilt. Spell
it hamilt::HamiltPW, as sto_hamilt_pw.cpp already does. Fixes the
MODULE_PW_Sto_Tool_UTs build failure in the Test and CUDA Test jobs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
source_hsolver/test, where the SDFT solver test used to live, builds
without __CUDA/__ROCM. module_stodft/test did not, so after the move the
CUDA build compiled the DEVICE_GPU instantiations of StoHSolverPW,
HSolverPW and FFT_CUDA into MODULE_PW_Sto_HSolver_UTs without linking
their GPU implementations, and the link failed.

Disable both for the directory, as source_hsolver/test does. All three
tests here only exercise CPU code; for Sto_Tool and Sto_Hamilt this just
drops GPU template instantiations they never call.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mohanchen
mohanchen merged commit 7873573 into deepmodeling:develop Sep 27, 2026
18 checks passed
Critsium-xy added a commit to Critsium-xy/abacus-develop that referenced this pull request Sep 28, 2026
.editorconfig has required `indent_style = space` with `indent_size = 4`
for the whole repository, but 339 files under source/ still indent with
tabs. This converts the leading whitespace of 248 of them.

253 files were selected when this was prepared. Since then, develop has
deleted source_lcao/setup_dm.h (deepmodeling#8000) and
source_pw/module_stodft/hamilt_sdft_pw.cpp (deepmodeling#8012), and already converted
source_base/module_out/binstream.{h,cpp} (deepmodeling#8025) and
source_pw/module_stodft/sto_hamilt_pw.h (renamed from hamilt_sdft_pw.h
in deepmodeling#8012), which leaves 248. The conversion follows files that develop
moved, e.g. onsite_proj_tools_stress.cpp is now under module_proj/
(deepmodeling#8007).

Scope. Three groups were deliberately left out:

  - 48 files touched by the pull requests open at the time of writing
    (deepmodeling#8000, deepmodeling#7924, deepmodeling#7906, deepmodeling#8005 and others), so this does not force a
    conflict on work in flight;
  - 5 vendored files: source_base/libm/ is ported from glibc-2.36 and
    carries its own LICENCE, and source_base/mcd.c is Softpixel
    MemCheckDeluxe under a BSD licence. Reformatting vendored sources
    makes future syncs with their upstream harder;
  - tabs that appear after the first non-blank character (alignment
    tabs, 1193 lines). Only leading indentation is converted.

Method and verification. `expand -i -t4`, which rewrites the initial
whitespace of a line and nothing else, followed by three checks:

  - `git diff -w --stat` is empty, so not one non-whitespace character
    changed anywhere in the diff;
  - of the 42 raw string literals in the changed files (222 lines, all
    in source_io/module_parameter/read_inp_out.cpp), none has a line
    that this commit touches. Leading whitespace inside `R"(...)"` is
    part of the string, so that was the one place a leading-whitespace
    rewrite could have changed behaviour;
  - no changed line follows a line ending in a backslash, so no
    backslash-continued string literal is affected either;
  - no file gained a CR.

Effect on tools/03_code_analysis/code_quality_score.py: average score
over source/ goes from 82.15 to 82.58 and the number of passing files
from 1560 to 1562.

Six files score 1 to 3 points lower, all through the `line_too_long`
rule, because the scorer counts a tab as a single character while it
renders as up to four columns. The lines were already over 120 columns
on screen; the tab was hiding it. One of them,
module_ri/exx_abfs_ctor_orbs.cpp, moves from 60 to 59 and so drops just
below the tool's pass line. Wrapping those lines would mean editing code
in a commit that is otherwise whitespace-only, so it is left for a
follow-up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Critsium-xy added a commit to Critsium-xy/abacus-develop that referenced this pull request Sep 30, 2026
.editorconfig has required `indent_style = space` with `indent_size = 4`
for the whole repository, but 339 files under source/ still indent with
tabs. This converts the leading whitespace of 246 of them.

253 files were selected when this was prepared. Since then, develop has
deleted two of them and already converted five others, which leaves 246:

  - deleted: source_lcao/setup_dm.h (deepmodeling#8000),
    source_pw/module_stodft/hamilt_sdft_pw.cpp (deepmodeling#8012);
  - already converted: source_base/module_out/binstream.{h,cpp} (deepmodeling#8025),
    source_pw/module_stodft/sto_hamilt_pw.h (renamed from
    hamilt_sdft_pw.h in deepmodeling#8012), source_io/module_ctrl/ctrl_output_pw.h
    and source_pw/module_pwdft/op_pw_nl.cpp (deepmodeling#8043).

Files that develop moved are converted at their new path, e.g.
onsite_proj_tools_stress.cpp is now under source_pw/module_proj/
(deepmodeling#8007).

Scope. Three groups were deliberately left out:

  - 48 files touched by the pull requests open at the time of writing
    (deepmodeling#8000, deepmodeling#7924, deepmodeling#7906, deepmodeling#8005 and others), so this does not force a
    conflict on work in flight;
  - 5 vendored files: source_base/libm/ is ported from glibc-2.36 and
    carries its own LICENCE, and source_base/mcd.c is Softpixel
    MemCheckDeluxe under a BSD licence. Reformatting vendored sources
    makes future syncs with their upstream harder;
  - tabs that appear after the first non-blank character (alignment
    tabs, 1193 lines). Only leading indentation is converted.

Method and verification. `expand -i -t4`, which rewrites the initial
whitespace of a line and nothing else, followed by three checks:

  - `git diff -w --stat` is empty, so not one non-whitespace character
    changed anywhere in the diff;
  - of the 42 raw string literals in the changed files (222 lines, all
    in source_io/module_parameter/read_inp_out.cpp), none has a line
    that this commit touches. Leading whitespace inside `R"(...)"` is
    part of the string, so that was the one place a leading-whitespace
    rewrite could have changed behaviour;
  - no changed line follows a line ending in a backslash, so no
    backslash-continued string literal is affected either;
  - no file gained a CR.

Effect on tools/03_code_analysis/code_quality_score.py: average score
over source/ goes from 82.15 to 82.58 and the number of passing files
from 1560 to 1562.

Six files score 1 to 3 points lower, all through the `line_too_long`
rule, because the scorer counts a tab as a single character while it
renders as up to four columns. The lines were already over 120 columns
on screen; the tab was hiding it. One of them,
module_ri/exx_abfs_ctor_orbs.cpp, moves from 60 to 59 and so drops just
below the tool's pass line. Wrapping those lines would mean editing code
in a commit that is otherwise whitespace-only, so it is left for a
follow-up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
mohanchen pushed a commit that referenced this pull request Sep 30, 2026
…o spaces (#8011)

* docs: fix two @file tags that name a different file

Doxygen's @file takes the name of the file it documents. These two
name a file that does not exist, so Doxygen attributes the block to the
wrong (or to no) file:

  source_base/ndarray.h                  said NDArray.h
  source_lcao/module_rt/band_energy.h    said bandenegy.h (also a typo)

Found by tools/03_code_analysis/code_quality_score.py (rule
doc_file_mismatch). The scan also flagged
source_pw/module_pwdft/radial_proj.h (said radial_projection.h), but
#8007 has since moved that header to source_pw/module_proj/ with the
tag already corrected, so it is no longer part of this commit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* style: convert leading tab indentation to spaces in 246 source files

.editorconfig has required `indent_style = space` with `indent_size = 4`
for the whole repository, but 339 files under source/ still indent with
tabs. This converts the leading whitespace of 246 of them.

253 files were selected when this was prepared. Since then, develop has
deleted two of them and already converted five others, which leaves 246:

  - deleted: source_lcao/setup_dm.h (#8000),
    source_pw/module_stodft/hamilt_sdft_pw.cpp (#8012);
  - already converted: source_base/module_out/binstream.{h,cpp} (#8025),
    source_pw/module_stodft/sto_hamilt_pw.h (renamed from
    hamilt_sdft_pw.h in #8012), source_io/module_ctrl/ctrl_output_pw.h
    and source_pw/module_pwdft/op_pw_nl.cpp (#8043).

Files that develop moved are converted at their new path, e.g.
onsite_proj_tools_stress.cpp is now under source_pw/module_proj/
(#8007).

Scope. Three groups were deliberately left out:

  - 48 files touched by the pull requests open at the time of writing
    (#8000, #7924, #7906, #8005 and others), so this does not force a
    conflict on work in flight;
  - 5 vendored files: source_base/libm/ is ported from glibc-2.36 and
    carries its own LICENCE, and source_base/mcd.c is Softpixel
    MemCheckDeluxe under a BSD licence. Reformatting vendored sources
    makes future syncs with their upstream harder;
  - tabs that appear after the first non-blank character (alignment
    tabs, 1193 lines). Only leading indentation is converted.

Method and verification. `expand -i -t4`, which rewrites the initial
whitespace of a line and nothing else, followed by three checks:

  - `git diff -w --stat` is empty, so not one non-whitespace character
    changed anywhere in the diff;
  - of the 42 raw string literals in the changed files (222 lines, all
    in source_io/module_parameter/read_inp_out.cpp), none has a line
    that this commit touches. Leading whitespace inside `R"(...)"` is
    part of the string, so that was the one place a leading-whitespace
    rewrite could have changed behaviour;
  - no changed line follows a line ending in a backslash, so no
    backslash-continued string literal is affected either;
  - no file gained a CR.

Effect on tools/03_code_analysis/code_quality_score.py: average score
over source/ goes from 82.15 to 82.58 and the number of passing files
from 1560 to 1562.

Six files score 1 to 3 points lower, all through the `line_too_long`
rule, because the scorer counts a tab as a single character while it
renders as up to four columns. The lines were already over 120 columns
on screen; the tab was hiding it. One of them,
module_ri/exx_abfs_ctor_orbs.cpp, moves from 60 to 59 and so drops just
below the tool's pass line. Wrapping those lines would mean editing code
in a commit that is otherwise whitespace-only, so it is left for a
follow-up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Refactor Refactor ABACUS codes The Absolute Zero Reduce the "entropy" of the code to 0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants