Skip to content

Dev m4 optimization - #29

Open
DiamonDinoia wants to merge 198 commits into
DEV_NEW_ALPHA_REBfrom
DEV_M4_OPTIMIZATION
Open

Dev m4 optimization#29
DiamonDinoia wants to merge 198 commits into
DEV_NEW_ALPHA_REBfrom
DEV_M4_OPTIMIZATION

Conversation

@DiamonDinoia

Copy link
Copy Markdown
Collaborator

Used clang builtin to vectorize iw4 accumulation.
Optimizations are disabled if gcc is used.

@DiamonDinoia
DiamonDinoia requested a review from Wentzell May 31, 2024 21:28
@Wentzell
Wentzell changed the base branch from unstable to DEV_NEW_ALPHA_REB June 3, 2024 18:53
@ahbarnett

Copy link
Copy Markdown
Collaborator

How's the FINUFFT speed vs NFFT3 working out for you?

@Wentzell
Wentzell force-pushed the DEV_NEW_ALPHA_REB branch from d7823eb to 1efbbd1 Compare June 18, 2024 21:07
@Wentzell
Wentzell force-pushed the DEV_M4_OPTIMIZATION branch from d450d90 to 791f048 Compare June 18, 2024 21:07
@Wentzell

Copy link
Copy Markdown
Member

How's the FINUFFT speed vs NFFT3 working out for you?

Hey @ahbarnett, switching to the FINUFFT backend has been a major performance improvement!
For the measurement that we are optimizing here the NUFFT transform is now subdominant again (~6%).

@Wentzell
Wentzell force-pushed the DEV_M4_OPTIMIZATION branch from 8565f44 to 607b619 Compare June 25, 2024 16:40
@Wentzell
Wentzell force-pushed the DEV_M4_OPTIMIZATION branch from 19c0e6a to e57982b Compare August 9, 2024 19:51
@Wentzell
Wentzell force-pushed the DEV_M4_OPTIMIZATION branch 7 times, most recently from 03852e0 to 405df56 Compare May 2, 2025 15:02
@Wentzell
Wentzell force-pushed the DEV_NEW_ALPHA_REB branch from 2e7d310 to 7ffa19f Compare May 2, 2025 15:12
@Wentzell
Wentzell force-pushed the DEV_M4_OPTIMIZATION branch from 405df56 to d7e36bd Compare May 2, 2025 15:13
Thoemi09 and others added 29 commits July 22, 2026 14:41
…and release branches

- for version switcher on the sphinx doc page
Set html_baseurl so every version build emits a rel="canonical" link to the
latest/ copy of each page. This tells search engines to prefer the latest docs
over older/unstable versions (and de-duplicates the identical latest/ and
newest-release folders).

Assisted-by: Claude <noreply@anthropic.com>
sphinx_rtd_theme 3.x ships an empty versions.html (the flyout is RTD-addons
only). Override it with _templates/versions.html to revive the bottom-left
'v: <version>' widget, populated from a static html_context['versions'] list.
Styled by the theme's existing .rst-versions CSS, toggled by theme.js.

Assisted-by: Claude <noreply@anthropic.com>
- remove latest
- use a dedicated cmake var VERSION_SUFFIX to distinguish unstable vs. release branches
- display unstable in case of non-release branches
# Conflicts:
#	CMakeLists.txt
#	README.md
#	doc/conf.py.in
The documentation is published at triqs.github.io/<repo> while PROJECT_NAME
is triqs_<repo>, so the canonical URL and all version-switcher links pointed
to non-existent pages. Use the actual website name instead.

Assisted-by: Claude <noreply@anthropic.com>
triqs_hartree_fock is resolved through external_dependency, which tries
find_package first unless Build_Deps=Always. When it instead builds from source
it does so as a subproject without EXCLUDE_FROM_ALL, so its own install rules
already ship the python module -- along with version.py and its cmake config,
which the rule here missed. The module was therefore installed twice.

The rule also pointed unconditionally at deps/triqs_hartree_fock, a path that
only exists when the sources happen to be checked out there: not when
external_dependency git-clones them into the build tree, and not when
find_package resolved the package from the system.

Dropping the rule makes every mode correct by construction. Verified that a
from-source install ships an unchanged set of triqs_hartree_fock files, now once
instead of twice, and that a Build_Deps=IfNotFound build against an installed
triqs_hartree_fock 4.0.0 resolves it from the system and installs none of it.

Assisted-by: Claude <noreply@anthropic.com>

squash
The <triqs/arrays/block_matrix.hpp> include in types.hpp was dead: block_matrix_t
is std::vector<matrix<...>> and the triqs::arrays::block_matrix<T> template it
pulled in is used nowhere in ctint. It only reached the bundled shim under
c++/triqs/, which is not installed, so a downstream C++ consumer of the installed
ctint headers failed to resolve the header. Drop the include and delete the
now-unreferenced shim (and the empty c++/triqs/ tree), closing the install gap
without shipping the shim into the triqs/ include namespace.

Assisted-by: Claude <noreply@anthropic.com>
poet was pulled in for a single utility: a compile-time unrolled loop over
[0, N). Reimplementing it as detail::static_for in nfft_buf.hpp is a handful of
lines and removes a dependency, its cmake resolution and its git clone.

Assisted-by: Claude <noreply@anthropic.com>
M3ph_tau, M3pp_tau, M3xph_tau, chi2_tau and chiAB_tau include nfft_buf.hpp
but use nothing from it. Only the six *_iw measures hold nfft_buf_t members,
which is also exactly the set of objects that reference FINUFFT symbols.

Assisted-by: Claude <noreply@anthropic.com>
nfft_buf.hpp is an installed public header, so including finufft.h and
<xsimd/xsimd.hpp> forced both dependencies' headers into our own prefix.
Everything that needs them now lives in a new nfft_buf.cpp, which explicitly
instantiates nfft_buf_t for the three Ranks its static_assert allows.

The finufft_opts struct becomes a local of each constructor rather than a
member: finufft_makeplan copies what it needs out of it and nothing reads it
afterwards, so it never had to be one. That is a prerequisite for dropping the
finufft.h include, and it also removes a ~15-field struct from every
nfft_buf_t, of which the M3/M4 measures hold n_blocks * n_orb^2.

The FINUFFT plan is reached through an opaque handle whose deleter is defined
out of line, so the header needs no FINUFFT declaration and the unique_ptr
member stays pointer-sized. push_back stays inline: it runs per Monte Carlo
accumulation and only reaches the new translation-unit boundary through
do_nfft(), once per nfft_buf_size pushes.

do_direct_bitwise() is now constrained with requires(Rank == 1) instead of
asserting it. The explicit instantiations instantiate every unconstrained
member, and that body is valid for Rank 1 only.

rebind() also needed triqs/utility/exceptions.hpp to be included explicitly:
TRIQS_ASSERT used to arrive transitively in the translation units that
happened to instantiate it.

Assisted-by: Claude <noreply@anthropic.com>
The prime-sum and odd-exponent machinery used to set up the direct kernels' per-
target exponent lists was a block of static members of nfft_buf_t, but none of it
depends on Rank -- it was templated by accident, and instantiated three times for
no reason. Nothing outside nfft_buf.{hpp,cpp} refers to any of it, and the only
uses are in the non-uniform-target constructor and the two kernel dispatch sites.

Move it verbatim into a file-local anonymous namespace in nfft_buf.cpp, dropping
the now-meaningless `static` and giving the whole block internal linkage. An
anonymous namespace rather than detail:: so that express_as_prime_sum does not
become an exported symbol of libtriqs_ctint_c.a.

This takes another 96 lines out of the installed header, which is now 262 lines
against 908 on unstable. The one behavioural difference is that the static_assert
validating the prime-sum table now fires when ctint is compiled rather than in
every translation unit that includes the header; it checks an internal invariant
of our own algorithm, so consumers gain nothing by re-verifying it.

Assisted-by: Claude <noreply@anthropic.com>
Two things in the installed header served no consumer:

- All three nfft_buf_t deduction guides are dead. Every construction site in
  c++/, test/ and the measures names the Rank explicitly as nfft_buf_t<1>, <2>
  or <3>, so class template argument deduction is never exercised. Two of the
  three also carried pre-existing clang-format violations.

- to_array_vector exists solely so the Rank==1 convenience constructor can
  delegate to the general one, so move it into detail rather than leave it as a
  free function in triqs::utility.

Assisted-by: Claude <noreply@anthropic.com>
Now that nfft_buf.cpp is the only translation unit touching either library, they
are pure build-time dependencies. Mark them PRIVATE and wrap them in
$<BUILD_INTERFACE:>: CMake records the private dependencies of a static library
as $<LINK_ONLY:...> in INTERFACE_LINK_LIBRARIES, which would both re-export them
and make install(EXPORT) fail on targets that are not in our export set.

That alone would leave the finufft symbols undefined in the installed archive,
so absorb finufft's objects into it via $<TARGET_OBJECTS:>. libtriqs_ctint_c.a
then defines finufft_makeplan and friends itself, and nothing of finufft needs
to be installed, exported or found again downstream. This is also why finufft
stays BUILD_ALWAYS. fftw is all that is left over; triqs_ctint-config.cmake
resolves it with find_library at consumer configure time rather than baking in
the absolute paths that finufft's own fftlibs list carries.

The install tree goes from 158 files to 51, with no third-party entry left in
it, and the exported interface names only triqs.

Assisted-by: Claude <noreply@anthropic.com>
conda-forge builds have no network, so every dependency has to come from the
host environment or from a source tarball declared in the recipe:

- triqs_hartree_fock is now a host and run requirement rather than something we
  bundle, and -DBuild_Deps=IfNotFound lets external_dependency() find it there
  instead of cloning it.
- fftw is both host and run: it is the one external dependency of the finufft
  code absorbed into our archive, a DT_NEEDED of the python modules and a
  link-time dependency of downstream C++ consumers.
- finufft has no C++ package on conda-forge, only the python bindings, so fetch
  its release tarball into deps/finufft where external_dependency() picks it up
  without a clone.

Assisted-by: Claude <noreply@anthropic.com>
The reference was stored by the constructor but never read, so clang warned
about it with -Wunused-private-field. The constructor keeps the parameter, as
every measure is built through the same interface.

Assisted-by: Claude <noreply@anthropic.com>
Match the style used across the other TRIQS repositories. The badge
target is unchanged: the concept DOI 10.5281/zenodo.15598402.

Assisted-by: Claude <noreply@anthropic.com>
Zenodo sends the badge SVG with cache-control: no-cache behind a
120 req/min per-IP rate limit. GitHub's camo proxy therefore re-fetches
it on every render from a shared IP pool, often getting a 429 that it
surfaces as a 502 broken image.

shields.io sends max-age=432000, so camo caches it instead. The link
target stays the concept DOI.

Assisted-by: Claude <noreply@anthropic.com>
The embedded plot images made the notebooks the largest source of
tracked text in the repository, so GitHub reported Jupyter Notebook as
the dominant language at 58%. Clearing the outputs shrinks them from
601K to 21K and leaves all cell sources untouched.

Assisted-by: Claude <noreply@anthropic.com>
(cherry picked from commit 8dc03fc)
measures/iw_accumulate.hpp adds xsimd kernels for the inner frequency
accumulation of M3pp, M3ph, M4, M4pp and M4ph. The five measure translation
units call the kernels instead of scalar loops. Clang needs
-ffp-contract=fast to emit the fma.

xsimd itself needs no new dependency entry: finufft already fetches it via
CPM and c++/triqs_ctint links it through $<BUILD_INTERFACE:xsimd>.
…layer

The frequency and orbital loops in iw_accumulate.hpp run as one loop nest,
so the batch loads happen once per tile instead of once per inner iteration.
The forwarding wrapper around the kernels is gone; the measures call the
kernel directly.
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.

9 participants