Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
edb3798
feat(exx): Ewald Coulomb input parameters and Exx_Info_RI fields for …
AroundPeking Oct 17, 2026
155366d
feat(ri): strict 2D/3D Coulomb kernels, Ewald tail machinery, and sym…
AroundPeking Oct 17, 2026
061e317
feat(rpa): strict-2D head sidecar and direct-Coulomb reader-v1 output…
AroundPeking Oct 17, 2026
3c36d81
test(ri): 2D reader-v1 producer case, regenerated Ewald refs, and che…
AroundPeking Oct 17, 2026
56509a2
docs(ri): key-formula comments for the strict-2D Coulomb and Ewald ta…
AroundPeking Oct 18, 2026
466579d
fix(ci): repair LibRI-gated test source path and replace #pragma once
AroundPeking Oct 19, 2026
4d9488c
fix(ci): close LibRI-gated operator test link and match reader CSR fo…
AroundPeking Oct 19, 2026
10f04df
fix(ci): make symmetry producer harness case-aware and round-trip Hex…
AroundPeking Oct 19, 2026
f836f43
Merge branch 'develop' into abacus-librpa-strict2d-oct17
mohanchen Oct 20, 2026
acbe254
refactor(xc): drop parameter.h include and align struct indentation
AroundPeking Oct 20, 2026
de29636
refactor(ri): communicator-aware MPI wrappers, explicit ExxLriRuntime…
AroundPeking Oct 20, 2026
d691c13
fix(ri): pass explicit ExxLriRuntime at the remaining constructors an…
AroundPeking Oct 20, 2026
26119a4
Merge branch 'develop' into abacus-librpa-strict2d-oct17
AroundPeking Oct 21, 2026
bbc21d4
Merge remote-tracking branch 'upstream/develop' into abacus-librpa-st…
AroundPeking Oct 21, 2026
925fcd8
Merge remote-tracking branch 'upstream/develop' into abacus-librpa-st…
AroundPeking Oct 23, 2026
bcc4bd9
test(validation): remove synthetic producer fixtures from validation_…
AroundPeking Oct 23, 2026
84d0923
fix(ci): restore ucell_io.cpp source for the restart_exx_csr test target
AroundPeking Oct 23, 2026
fcebd02
fix(ri): address review round on MPI wrappers, defaults, and test hyg…
AroundPeking Oct 23, 2026
5619814
Merge remote-tracking branch 'upstream/develop' into abacus-librpa-st…
AroundPeking Oct 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
64 changes: 63 additions & 1 deletion source/source_base/element_basis_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include "element_basis_index.h"

#include <stdexcept>
#include <vector>

namespace ModuleBase
{

Expand Down Expand Up @@ -37,4 +40,63 @@ Element_Basis_Index::construct_index( const Range &range )
return index;
}

}
Element_Basis_Index::IndexLNM
Element_Basis_Index::construct_index( const Range &range, const IndexPermutation &old_to_new )
{
if( old_to_new.empty() )
{
return construct_index(range);
}

IndexLNM index;
index.resize( range.size() );
for( std::size_t T=0; T!=range.size(); ++T )
{
std::size_t count_size = 0;
for( std::size_t L=0; L!=range[T].size(); ++L )
{
count_size += range[T][L].N * range[T][L].M;
}

const bool use_permutation = (T < old_to_new.size() && !old_to_new[T].empty());
if( use_permutation )
{
if( old_to_new[T].size() != count_size )
{
throw std::invalid_argument("Element_Basis_Index::construct_index permutation size mismatch.");
}

std::vector<bool> seen(count_size, false);
for( const std::size_t new_index : old_to_new[T] )
{
if( new_index >= count_size || seen[new_index] )
{
throw std::invalid_argument("Element_Basis_Index::construct_index permutation is not bijective.");
}
seen[new_index] = true;
}
}

std::size_t count = 0;
index[T].resize( range[T].size() );
for( std::size_t L=0; L!=range[T].size(); ++L )
{
index[T][L].resize( range[T][L].N );
for( std::size_t N=0; N!=range[T][L].N; ++N )
{
index[T][L][N].resize( range[T][L].M );
for( std::size_t M=0; M!=range[T][L].M; ++M )
{
index[T][L][N][M] = use_permutation ? old_to_new[T][count] : count;
++count;
}
}
index[T][L].N = range[T][L].N;
index[T][L].M = range[T][L].M;
}
index[T].count_size = count_size;
}
return index;
}

}
48 changes: 25 additions & 23 deletions source/source_base/element_basis_index.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,36 @@ namespace Element_Basis_Index
{
//private:

struct NM
{
public:
std::size_t N;
std::size_t M;
};

class Index_TL: public std::vector<std::vector<std::size_t>>
{
public:
std::size_t N;
std::size_t M;
};

class Index_T: public std::vector<Index_TL>
{
public:
std::size_t count_size;
};
struct NM
{
public:
std::size_t N;
std::size_t M;
};

class Index_TL: public std::vector<std::vector<std::size_t>>
{
public:
std::size_t N;
std::size_t M;
};

class Index_T: public std::vector<Index_TL>
{
public:
std::size_t count_size;
};

//public:

typedef std::vector<std::vector<NM>> Range; // range[T][L]
typedef std::vector<Index_T> IndexLNM; // index[T][L][N][M]
typedef std::vector<std::vector<NM>> Range; // range[T][L]
typedef std::vector<Index_T> IndexLNM; // index[T][L][N][M]
typedef std::vector<std::vector<std::size_t>> IndexPermutation; // old_to_new[T][old_index]

extern IndexLNM construct_index( const Range &range );
extern IndexLNM construct_index( const Range &range );
extern IndexLNM construct_index( const Range &range, const IndexPermutation &old_to_new );
}

}

#endif
#endif
31 changes: 31 additions & 0 deletions source/source_base/parallel_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,35 @@ void bcast_char(char* object, const int n)
#endif
}

#ifdef __MPI
void bcast_int(int* object, const int n, const MPI_Comm mpi_comm, const int root)
{
MPI_Bcast(object, n, MPI_INT, root, mpi_comm);
}

void bcast_double(double* object, const int n, const MPI_Comm mpi_comm, const int root)
{
MPI_Bcast(object, n, MPI_DOUBLE, root, mpi_comm);
}

int my_rank(const MPI_Comm mpi_comm)
{
int rank = 0;
MPI_Comm_rank(mpi_comm, &rank);
return rank;
}

int nproc(const MPI_Comm mpi_comm)
{
int size = 1;
MPI_Comm_size(mpi_comm, &size);
return size;
}

void barrier(const MPI_Comm mpi_comm)
{
MPI_Barrier(mpi_comm);
}
#endif

} // namespace Parallel_Common
13 changes: 13 additions & 0 deletions source/source_base/parallel_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ void bcast_double(double& object);
void bcast_int(int& object);
void bcast_bool(bool& object);

#ifdef __MPI
//(3) communicator- and root-aware counterparts for the sub-communicator
// stages (RI/RPA) that run outside MPI_COMM_WORLD and outside root 0
void bcast_int(int* object, const int n, const MPI_Comm mpi_comm, const int root);
void bcast_double(double* object, const int n, const MPI_Comm mpi_comm, const int root);
/// @brief Rank of the caller on an arbitrary communicator.
int my_rank(const MPI_Comm mpi_comm);
/// @brief Number of ranks on an arbitrary communicator.
int nproc(const MPI_Comm mpi_comm);
/// @brief Barrier on an arbitrary communicator.
void barrier(const MPI_Comm mpi_comm);
#endif

} // namespace Parallel_Common

#endif
76 changes: 76 additions & 0 deletions source/source_base/parallel_reduce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const MPI_Datatype Parallel_Reduce::MPI_Type<float>::value = MPI_FLOAT;
const MPI_Datatype Parallel_Reduce::MPI_Type<std::complex<double>>::value = MPI_DOUBLE_COMPLEX;
const MPI_Datatype Parallel_Reduce::MPI_Type<std::complex<float>>::value = MPI_C_FLOAT_COMPLEX;
const MPI_Datatype Parallel_Reduce::MPI_Type<long long>::value = MPI_LONG_LONG;
const MPI_Datatype Parallel_Reduce::MPI_Type<unsigned long long>::value = MPI_UNSIGNED_LONG_LONG;
#endif

template <typename T>
Expand Down Expand Up @@ -126,6 +127,81 @@ template void Parallel_Reduce::reduce_max<double>(double&);
template void Parallel_Reduce::reduce_min_pool<double>(const int&, double&);
template void Parallel_Reduce::reduce_max_pool<double>(const int&, double&);

#ifdef __MPI
template <typename T>
void Parallel_Reduce::reduce_all(const MPI_Comm mpi_comm, T& object)
{
MPI_Allreduce(MPI_IN_PLACE, &object, 1, MPI_Type<T>::value, MPI_SUM, mpi_comm);
}

template <typename T>
void Parallel_Reduce::reduce_all(const MPI_Comm mpi_comm, T* object, const int n)
{
MPI_Allreduce(MPI_IN_PLACE, object, n, MPI_Type<T>::value, MPI_SUM, mpi_comm);
}

template <typename T>
void Parallel_Reduce::reduce_max(const MPI_Comm mpi_comm, T& object)
{
MPI_Allreduce(MPI_IN_PLACE, &object, 1, MPI_Type<T>::value, MPI_MAX, mpi_comm);
}

template <typename T>
void Parallel_Reduce::reduce_min(const MPI_Comm mpi_comm, T& object)
{
MPI_Allreduce(MPI_IN_PLACE, &object, 1, MPI_Type<T>::value, MPI_MIN, mpi_comm);
}

void Parallel_Reduce::reduce_max_loc(const MPI_Comm mpi_comm, double& value, int& rank)
{
struct MaxLoc
{
double value;
int rank;
};
MaxLoc local{value, rank};
MaxLoc global{};
MPI_Allreduce(&local, &global, 1, MPI_DOUBLE_INT, MPI_MAXLOC, mpi_comm);
value = global.value;
rank = global.rank;
}

void Parallel_Reduce::gather_int_all(const MPI_Comm mpi_comm, int& v, int* all)
{
assert(all != nullptr);
MPI_Allgather(&v, 1, MPI_INT, all, 1, MPI_INT, mpi_comm);
}

void Parallel_Reduce::gatherv_int_all(const MPI_Comm mpi_comm,
const int* send_buffer,
const int send_count,
int* receive_buffer,
const int* receive_counts,
const int* receive_displacements)
{
assert(receive_buffer != nullptr);
MPI_Allgatherv(send_buffer, send_count, MPI_INT, receive_buffer, receive_counts, receive_displacements,
MPI_INT, mpi_comm);
}

template void Parallel_Reduce::reduce_all<int>(const MPI_Comm, int&);
template void Parallel_Reduce::reduce_all<double>(const MPI_Comm, double&);
template void Parallel_Reduce::reduce_all<unsigned long long>(const MPI_Comm, unsigned long long&);

template void Parallel_Reduce::reduce_all<int>(const MPI_Comm, int*, const int);
template void Parallel_Reduce::reduce_all<double>(const MPI_Comm, double*, const int);
template void Parallel_Reduce::reduce_all<unsigned long long>(const MPI_Comm, unsigned long long*, const int);

template void Parallel_Reduce::reduce_max<int>(const MPI_Comm, int&);
template void Parallel_Reduce::reduce_max<double>(const MPI_Comm, double&);
template void Parallel_Reduce::reduce_max<unsigned long long>(const MPI_Comm, unsigned long long&);

template void Parallel_Reduce::reduce_min<int>(const MPI_Comm, int&);
template void Parallel_Reduce::reduce_min<double>(const MPI_Comm, double&);
template void Parallel_Reduce::reduce_min<unsigned long long>(const MPI_Comm, unsigned long long&);
#endif


void Parallel_Reduce::reduce_double_grid(double* object, const int n)
{
#ifdef __MPI
Expand Down
32 changes: 32 additions & 0 deletions source/source_base/parallel_reduce.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ struct MPI_Type<long long>
{
static const MPI_Datatype value;
};

template <>
struct MPI_Type<unsigned long long>
{
static const MPI_Datatype value;
};
#endif

/// reduce in all process
Expand Down Expand Up @@ -82,6 +88,32 @@ void reduce_double_allpool(const int& npool, const int& nproc_in_pool, double* o

void gather_int_all(int& v, int* all);

#ifdef __MPI
/// Communicator-aware counterparts of the MPI_COMM_WORLD-bound helpers above.
/// The RI and RPA stages run on caller-provided sub-communicators, which those
/// helpers cannot express; route every reduction on such a communicator
/// through these overloads so the raw MPI calls stay centralized here.
template <typename T>
void reduce_all(const MPI_Comm mpi_comm, T& object);
template <typename T>
void reduce_all(const MPI_Comm mpi_comm, T* object, const int n);
template <typename T>
void reduce_max(const MPI_Comm mpi_comm, T& object);
template <typename T>
void reduce_min(const MPI_Comm mpi_comm, T& object);
/// @brief Largest value together with the rank that supplied it (MPI_MAXLOC).
void reduce_max_loc(const MPI_Comm mpi_comm, double& value, int& rank);
/// @brief Allgather one int per rank on an arbitrary communicator.
void gather_int_all(const MPI_Comm mpi_comm, int& v, int* all);
/// @brief Allgatherv with per-rank counts and displacements on an arbitrary communicator.
void gatherv_int_all(const MPI_Comm mpi_comm,
const int* send_buffer,
const int send_count,
int* receive_buffer,
const int* receive_counts,
const int* receive_displacements);
#endif

} // namespace Parallel_Reduce

#endif
3 changes: 3 additions & 0 deletions source/source_cell/module_symmetry/irred_sec.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace ModuleSymmetry
{
class SymmetryRotationTestAccess;

using Tap = std::pair<int, int>;
using TC = std::array<int, 3>;
using TapR = std::pair<Tap, TC>;
Expand Down Expand Up @@ -149,6 +151,7 @@ namespace ModuleSymmetry

friend class Symmetry_rotation;
friend class Symmetry_rotation_k;
friend class SymmetryRotationTestAccess;
};
}

Expand Down
5 changes: 3 additions & 2 deletions source/source_cell/module_symmetry/symm_rotation_k.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,9 @@ namespace ModuleSymmetry
// calculate Wigner D matrix
double Symmetry_rotation_k::wigner_d(const double beta, const int l, const int m1, const int m2) const
{
auto factorial = [](int n) -> int {
int result = 1;
// The four-factorial product overflows int for l >= 5, so evaluate in double.
auto factorial = [](int n) -> double {
double result = 1;
for (int i = 1;i <= n;++i) { result *= i;
}
return result;
Expand Down
4 changes: 2 additions & 2 deletions source/source_esolver/esolver_lr_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void ModuleESolver::ESolver_LR<T, TR>::initialize_from_ks_(UnitCell& ucell, cons
exx_info.info_ri.files_abfs = ucell.abfs_orbital_files;
exx_info.info_opt_abfs.files_abfs = ucell.abfs_orbital_files;
exx_info.info_opt_abfs.files_jles = ucell.jle_orbital_files;
this->exx_lri = std::make_shared<Exx_LRI<T>>(exx_info.info_ri);
this->exx_lri = std::make_shared<Exx_LRI<T>>(exx_info.info_ri, make_exx_lri_runtime());
this->exx_lri->init(MPI_COMM_WORLD, ucell, this->kv, ks_sol.orb_);
this->exx_owned_ = true; // the position-dependent `cal_exx_ions` is left to `refresh_from_ks_`
}
Expand Down Expand Up @@ -487,7 +487,7 @@ void ModuleESolver::ESolver_LR<T, TR>::initialize_from_unitcell_(UnitCell& ucell
exx_info.info_ri.files_abfs = ucell.abfs_orbital_files;
exx_info.info_opt_abfs.files_abfs = ucell.abfs_orbital_files;
exx_info.info_opt_abfs.files_jles = ucell.jle_orbital_files;
this->exx_lri = std::make_shared<Exx_LRI<T>>(exx_info.info_ri);
this->exx_lri = std::make_shared<Exx_LRI<T>>(exx_info.info_ri, make_exx_lri_runtime());
this->exx_lri->init(MPI_COMM_WORLD, ucell,this->kv, orb);
this->exx_lri->cal_exx_ions(ucell,this->inp_->out_ri_cv);
}
Expand Down
2 changes: 1 addition & 1 deletion source/source_esolver/esolver_lr_lcao_bse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ void ESolver_BSE<T, TR>::lri_init()
std::map<TA, std::map<TAC, RI::Tensor<T>>> Ws_in;
// if (GlobalV::MY_RANK == 0) // comment to read from all processes to avoid communication
// {
Cs_in = LRI_CV_Tools::read_Cs_ao_all<T>(this->rpa_dir);
Cs_in = LRI_CV_Tools::read_Cs_ao_all<T>(this->rpa_dir, 0.0);
if (this->inp_->ri_hartree_benchmark == "aims-librpa" )
{
Vs_in = LR_IO::read_coulomb_mat_general_k<T, T>(this->rpa_dir, Cs_in, this->kRlist);
Expand Down
Loading
Loading