Skip to content
Open
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
e1dba87
set hardcoded biorthogonal coeffs till rank 7
ABesharat Oct 13, 2025
1323fc6
rank 7
ABesharat Oct 13, 2025
897a42a
discard redundant assertion
ABesharat Oct 13, 2025
a22809c
better name: computed_coefficients
ABesharat Oct 13, 2025
dbcd4e5
add hardcoded file to cmakelist
ABesharat Oct 13, 2025
8fd5be0
v2: correct rescaling factor
ABesharat Oct 13, 2025
47ccfe1
renaming original coeffs to computed_coefficients
ABesharat Oct 13, 2025
93829df
Merge remote-tracking branch 'origin/azam/feature/hardcoded_biorthogo…
ABesharat Oct 13, 2025
70ef68a
renaming
ABesharat Nov 11, 2025
4fc0898
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 8, 2025
fc0dcda
discard old coefficients
ABesharat Dec 8, 2025
f309f62
discard only the old coefficients, not num_perms
ABesharat Dec 8, 2025
b5da4b8
no inline anymore for performance
ABesharat Dec 10, 2025
25bb6f4
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 10, 2025
3926bde
at max rank 6 is enough
ABesharat Dec 10, 2025
e485b9c
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 12, 2025
87b8177
test_eval_ta: add rank 4 nns test, fix rank 3
ABesharat Dec 13, 2025
5ca6d55
test_eval_btas: fix nns for rank 3
ABesharat Dec 13, 2025
188825c
add hardcoded biortho coeffs and nns projection
ABesharat Dec 13, 2025
8e66ac7
fix include
ABesharat Dec 13, 2025
1dc89b3
use hardcoded biortho coeffs for rank<=6, otherwise use computed ones
ABesharat Dec 13, 2025
53b47be
do not call nns with int type ,use hardcoded nns for rank<=6, otherwi…
ABesharat Dec 13, 2025
a28d886
make libperm public to build the same order of permutations
ABesharat Dec 13, 2025
ab8f453
fix include for Eigen!
ABesharat Dec 13, 2025
d5b20f6
change the name of hardcoded nns fn
ABesharat Dec 14, 2025
278dcc3
renaming again!
ABesharat Dec 14, 2025
aede8b3
renaming hardcoded_biortho_coeffs fn
ABesharat Dec 14, 2025
4b1a92f
change assert to SEQUANT_ASSERT
ABesharat Dec 15, 2025
8ee5a57
no need to have rescaling for v2. new nns is enough for restoring WK …
ABesharat Dec 18, 2025
a3345c4
documentation correction
ABesharat Dec 18, 2025
78dc616
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 18, 2025
d2323d0
use abort for calling nns with int type
ABesharat Dec 21, 2025
0f4ab0c
normalization factor of S
ABesharat Dec 22, 2025
acc25f8
Remove additional print statements, cleaning
ABesharat Dec 25, 2025
877e3d4
address the requested changes
ABesharat Dec 25, 2025
0a60656
address the requested changes, except the namespace
ABesharat Dec 26, 2025
14fbd13
extract libperm calls into a helper function to avoid public dependency
ABesharat Dec 27, 2025
f4a0c82
Optimize build command with parallel jobs
ABesharat Dec 28, 2025
7087e16
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 28, 2025
519e68a
a better name: biorth_threshold
ABesharat Jan 3, 2026
2e67e8e
use default threshold for compute_nns_p_matricx to avoid an additiona…
ABesharat Jan 3, 2026
aa7a41c
add some documentations
ABesharat Jan 11, 2026
69ab3a1
clear documentation
ABesharat Jan 12, 2026
af93394
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Jan 12, 2026
2d10389
apply encapsulation for nns
ABesharat Jan 15, 2026
a9a17b1
memoize nns_projection weights
ABesharat Jan 16, 2026
afed9c4
add include
ABesharat Jan 16, 2026
1ca7fa6
dox cleanup
evaleev Jan 16, 2026
ff05b7c
nns_projection_weights: no third lock needed to return the result
evaleev Jan 16, 2026
4732bf5
removed the no-longer-used biorthogonalization_hardcoded.ipp
evaleev Jan 16, 2026
ecde7eb
memoize biorthogonal coeffs by lambda to have separate cache for hard…
ABesharat Jan 16, 2026
5f490ef
Merge remote-tracking branch 'refs/remotes/origin/azam/feature/hardco…
ABesharat Jan 16, 2026
333f296
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Jan 16, 2026
6697a4e
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Jan 16, 2026
8f42dac
remove the redundant header include
ABesharat Jan 16, 2026
2e171a8
move Eigen usage from public header to implementation
ABesharat Jan 16, 2026
370bd30
remove the redundant header include
ABesharat Jan 16, 2026
e6adbab
biorthogonalization.cpp: forward declaration to avoid having Eigen in…
ABesharat Jan 16, 2026
72dac7e
move hardcoded contents to biorthogonalization.cpp and hpp
ABesharat Jan 17, 2026
711e460
add to header file to keep the documentation
ABesharat Jan 17, 2026
f8f3115
make compute-nns compact
ABesharat Jan 18, 2026
9d98421
using auto instead of std::size_t
ABesharat Jan 21, 2026
c3a6c07
remove biorthogonalization from IR since it is too domain-specific
evaleev Jan 21, 2026
c8cf5b9
fix the cmake
ABesharat Jan 21, 2026
6c138ef
fix nns call in eval_ta and eval_btas
ABesharat Jan 22, 2026
5b64bdd
refactor SQ/eval to live in core/eval and separate backend-specific a…
evaleev Jan 23, 2026
93fab50
Merge pull request #465 from ValeevGroup/evaleev/feature/conditional-…
bimalgaudel Jan 23, 2026
30f76e0
fix Copilot suggestions
ABesharat Jan 23, 2026
40663b4
biorthogonalization: renames/restruct
evaleev Jan 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ if (Boost_IS_MODULARIZED)
endif()
if (TARGET tiledarray)
target_link_libraries(SeQuant PUBLIC tiledarray)
target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_TILEDARRAY=1 SEQUANT_HAS_BTAS=1)
endif ()
if (SEQUANT_HAS_EXECUTION_HEADER_STANDALONE OR SEQUANT_HAS_EXECUTION_HEADER_WITH_TBB)
target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_EXECUTION_HEADER)
Expand Down
53 changes: 13 additions & 40 deletions SeQuant/core/eval/eval.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#ifndef SEQUANT_EVAL_EVAL_HPP
#define SEQUANT_EVAL_EVAL_HPP

#include <SeQuant/core/eval/eval_fwd.hpp>

#include <SeQuant/core/container.hpp>
#include <SeQuant/core/eval/cache_manager.hpp>
#include <SeQuant/core/eval/eval_fwd.hpp>
#include <SeQuant/core/eval/result.hpp>
#include <SeQuant/core/eval_node.hpp>
#include <SeQuant/core/expr.hpp>
Expand Down Expand Up @@ -60,9 +61,6 @@ enum struct EvalMode {
SumInplace,
Symmetrize,
Antisymmetrize,
/// NNS projection of Wang-Knizia biorthogonalization
/// @sa ResultPtr::biorthogonal_nns_project
BiorthogonalNNSProject,
Unknown
};

Expand All @@ -80,18 +78,17 @@ enum struct EvalMode {
}

[[nodiscard]] constexpr auto to_string(EvalMode mode) noexcept {
return (mode == EvalMode::Constant) ? "Constant"
: (mode == EvalMode::Variable) ? "Variable"
: (mode == EvalMode::Tensor) ? "Tensor"
: (mode == EvalMode::Permute) ? "Permute"
: (mode == EvalMode::Product) ? "Product"
: (mode == EvalMode::MultByPhase) ? "MultByPhase"
: (mode == EvalMode::Sum) ? "Sum"
: (mode == EvalMode::SumInplace) ? "SumInplace"
: (mode == EvalMode::Symmetrize) ? "Symmetrize"
: (mode == EvalMode::Antisymmetrize) ? "Antisymmetrize"
: (mode == EvalMode::BiorthogonalNNSProject) ? "BiorthogonalNNSProject"
: "??";
return (mode == EvalMode::Constant) ? "Constant"
: (mode == EvalMode::Variable) ? "Variable"
: (mode == EvalMode::Tensor) ? "Tensor"
: (mode == EvalMode::Permute) ? "Permute"
: (mode == EvalMode::Product) ? "Product"
: (mode == EvalMode::MultByPhase) ? "MultByPhase"
: (mode == EvalMode::Sum) ? "Sum"
: (mode == EvalMode::SumInplace) ? "SumInplace"
: (mode == EvalMode::Symmetrize) ? "Symmetrize"
: (mode == EvalMode::Antisymmetrize) ? "Antisymmetrize"
: "??";
}

enum struct CacheMode { Store, Access, Release };
Expand Down Expand Up @@ -543,30 +540,6 @@ ResultPtr evaluate_antisymm(Args&&... args) {
return result;
}

/// \brief Calls sequant::evaluate followed by
/// ResultPtr::biorthogonal_nns_project \return Evaluated result as ResultPtr.
/// \sa ResultPtr::biorthogonal_nns_project
template <Trace EvalTrace = Trace::Default, typename... Args>
ResultPtr evaluate_biorthogonal_nns_project(Args&&... args) {
ResultPtr pre = evaluate<EvalTrace>(std::forward<Args>(args)...);
SEQUANT_ASSERT(pre);

auto const& n0 = node0(arg0(std::forward<Args>(args)...));

ResultPtr result;
auto time = timed_eval_inplace([&]() {
result = pre->biorthogonal_nns_project(n0->as_tensor().bra_rank());
});

// logging
if constexpr (trace(EvalTrace)) {
auto stat = log::EvalStat{.mode = log::EvalMode::BiorthogonalNNSProject,
.time = time,
.memory = log::bytes(pre, result)};
log::eval(stat, n0->label());
}
return result;
}
} // namespace sequant

#endif // SEQUANT_EVAL_EVAL_HPP
191 changes: 2 additions & 189 deletions SeQuant/core/eval/result.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#ifndef SEQUANT_EVAL_RESULT_HPP
#define SEQUANT_EVAL_RESULT_HPP

#include <SeQuant/core/eval/eval_fwd.hpp>

#include <SeQuant/core/algorithm.hpp>
#include <SeQuant/core/container.hpp>
#include <SeQuant/core/eval/eval_fwd.hpp>
#include <SeQuant/core/hash.hpp>
#include <SeQuant/core/index.hpp>
#include <SeQuant/core/logger.hpp>
Expand Down Expand Up @@ -340,157 +341,6 @@ auto particle_antisymmetrize_btas(btas::Tensor<Args...> const& arr,
return result;
}

/// \brief This function is used to implement
/// ResultPtr::biorthogonal_nns_project for TA::DistArray
///
/// \param arr The array to be "cleaned up"
/// \param bra_rank The rank of the bra indices
///
/// \return The cleaned TA::DistArray.
template <typename... Args>
auto biorthogonal_nns_project_ta(TA::DistArray<Args...> const& arr,
size_t bra_rank) {
using ranges::views::iota;
size_t const rank = arr.trange().rank();
SEQUANT_ASSERT(bra_rank <= rank);
size_t const ket_rank = rank - bra_rank;

if (rank <= 4) {
return arr;
}

using numeric_type = typename TA::DistArray<Args...>::numeric_type;

size_t factorial_ket = 1;
for (size_t i = 2; i <= ket_rank; ++i) {
factorial_ket *= i;
}
numeric_type norm_factor = numeric_type(1) / numeric_type(factorial_ket);

TA::DistArray<Args...> result;

perm_t perm = iota(size_t{0}, rank) | ranges::to<perm_t>;
perm_t bra_perm = iota(size_t{0}, bra_rank) | ranges::to<perm_t>;
perm_t ket_perm = iota(bra_rank, rank) | ranges::to<perm_t>;

const auto lannot = ords_to_annot(perm);

auto process_permutations = [&lannot](const TA::DistArray<Args...>& input_arr,
size_t range_rank, perm_t range_perm,
const std::string& other_annot,
bool is_bra) -> TA::DistArray<Args...> {
if (range_rank <= 1) return input_arr;
TA::DistArray<Args...> result;

auto callback = [&]([[maybe_unused]] int parity) {
const auto range_annot = ords_to_annot(range_perm);
const auto annot = other_annot.empty()
? range_annot
: (is_bra ? range_annot + "," + other_annot
: other_annot + "," + range_annot);

// ignore parity, all permutations get same coefficient
numeric_type p_ = 1;
if (result.is_initialized()) {
result(lannot) += p_ * input_arr(annot);
} else {
result(lannot) = p_ * input_arr(annot);
}
};
antisymmetric_permutation(ParticleRange{range_perm.begin(), range_rank},
callback);
return result;
};

// identity term with coefficient +1
result(lannot) = arr(lannot);

// process only ket permutations with coefficient norm_factor
if (ket_rank > 1) {
const auto bra_annot = bra_rank == 0 ? "" : ords_to_annot(bra_perm);
auto ket_result =
process_permutations(arr, ket_rank, ket_perm, bra_annot, false);

result(lannot) -= norm_factor * ket_result(lannot);
}

TA::DistArray<Args...>::wait_for_lazy_cleanup(result.world());
return result;
}

/// \brief This function is used to implement
/// ResultPtr::biorthogonal_nns_project for btas::Tensor
///
/// \param arr The array to be "cleaned up"
/// \param bra_rank The rank of the bra indices
///
/// \return The cleaned btas::Tensor.
template <typename... Args>
auto biorthogonal_nns_project_btas(btas::Tensor<Args...> const& arr,
size_t bra_rank) {
using ranges::views::concat;
using ranges::views::iota;
size_t const rank = arr.rank();
SEQUANT_ASSERT(bra_rank <= rank);
size_t const ket_rank = rank - bra_rank;

if (rank <= 4) {
return arr;
}

using numeric_type = typename btas::Tensor<Args...>::numeric_type;

size_t factorial_ket = 1;
for (size_t i = 2; i <= ket_rank; ++i) {
factorial_ket *= i;
}
numeric_type norm_factor = numeric_type(1) / numeric_type(factorial_ket);

perm_t bra_perm = iota(size_t{0}, bra_rank) | ranges::to<perm_t>;
perm_t ket_perm = iota(bra_rank, rank) | ranges::to<perm_t>;
const auto lannot = iota(size_t{0}, rank) | ranges::to<perm_t>;

auto process_permutations = [&lannot](const btas::Tensor<Args...>& input_arr,
size_t range_rank, perm_t range_perm,
const perm_t& other_perm, bool is_bra) {
if (range_rank <= 1) return input_arr;
btas::Tensor<Args...> result{input_arr.range()};
result.fill(0);

auto callback = [&]([[maybe_unused]] int parity) {
const auto annot =
is_bra ? concat(range_perm, other_perm) | ranges::to<perm_t>()
: concat(other_perm, range_perm) | ranges::to<perm_t>();

// ignore parity, all permutations get same coefficient
numeric_type p_ = 1;
btas::Tensor<Args...> temp;
btas::permute(input_arr, lannot, temp, annot);
btas::scal(p_, temp);
result += temp;
};

antisymmetric_permutation(ParticleRange{range_perm.begin(), range_rank},
callback);
return result;
};

// identity term with coefficient +1
auto result = arr;

// process only ket permutations with coefficient norm_factor
if (ket_rank > 1) {
const auto bra_annot = bra_rank == 0 ? perm_t{} : bra_perm;
auto ket_result =
process_permutations(arr, ket_rank, ket_perm, bra_annot, false);

btas::scal(norm_factor, ket_result);
result -= ket_result;
}

return result;
}

template <typename... Args>
inline void log_result(Args const&... args) noexcept {
auto& l = Logger::instance();
Expand Down Expand Up @@ -631,19 +481,6 @@ class Result {
///
[[nodiscard]] virtual ResultPtr antisymmetrize(size_t bra_rank) const = 0;

/// \brief Implements "biorthogonal cleanup" of closed-shell
/// more compact spintraced equations produced via method of
/// <a href="https://arxiv.org/abs/1805.00565">Wang and Knizia</a>.
///
/// For 3-body residual (`bra_rank=3`) this implements Eq. (41) of the
/// Wang/Knizia paper, same as the first line of Figure 1.
/// For 4-body residual this implements the first line of Figure 2.
/// The implementation is for arbitrary ranks.
/// @param bra_rank the particle rank of the residual tensor (i.e.
/// its order halved)
[[nodiscard]] virtual ResultPtr biorthogonal_nns_project(
size_t bra_rank) const = 0;

[[nodiscard]] bool has_value() const noexcept;

[[nodiscard]] virtual ResultPtr mult_by_phase(std::int8_t) const = 0;
Expand Down Expand Up @@ -755,11 +592,6 @@ class ResultScalar final : public Result {
throw unimplemented_method("antisymmetrize");
}

[[nodiscard]] ResultPtr biorthogonal_nns_project(
[[maybe_unused]] size_t bra_rank) const override {
throw unimplemented_method("biorthogonal_nns_project");
}

[[nodiscard]] ResultPtr mult_by_phase(std::int8_t factor) const override {
return eval_result<ResultScalar<T>>(value() * T(factor));
}
Expand Down Expand Up @@ -901,12 +733,6 @@ class ResultTensorTA final : public Result {
particle_antisymmetrize_ta(get<ArrayT>(), bra_rank));
}

[[nodiscard]] ResultPtr biorthogonal_nns_project(
size_t bra_rank) const override {
return eval_result<this_type>(
biorthogonal_nns_project_ta(get<ArrayT>(), bra_rank));
}

private:
[[nodiscard]] std::size_t size_in_bytes() const final {
auto& v = get<ArrayT>();
Expand Down Expand Up @@ -1055,13 +881,6 @@ class ResultTensorOfTensorTA final : public Result {
return nullptr;
}

[[nodiscard]] ResultPtr biorthogonal_nns_project(
[[maybe_unused]] size_t bra_rank) const override {
// or? throw unimplemented_method("biorthogonal_nns_project");
// not implemented yet, I think I need it for CSV
return nullptr;
}

private:
[[nodiscard]] std::size_t size_in_bytes() const final {
auto& v = get<ArrayT>();
Expand Down Expand Up @@ -1164,12 +983,6 @@ class ResultTensorBTAS final : public Result {
particle_antisymmetrize_btas(get<T>(), bra_rank));
}

[[nodiscard]] ResultPtr biorthogonal_nns_project(
[[maybe_unused]] size_t bra_rank) const override {
return eval_result<ResultTensorBTAS<T>>(
biorthogonal_nns_project_btas(get<T>(), bra_rank));
}

private:
[[nodiscard]] std::size_t size_in_bytes() const final {
static_assert(std::is_arithmetic_v<typename T::value_type>);
Expand Down
Loading