Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions include/RI/distribute/Distribute_Equally.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ namespace Distribute_Equally
const std::array<Tcell,Ndim> &period,
const std::size_t num_index,
const bool flag_task_repeatable);

template<typename Tindex>
extern void distribute_atom_and_k_pair(
const MPI_Comm &mpi_comm,
const std::size_t nat,
const std::size_t nk,
std::vector<Tindex> &list_I,
std::vector<Tindex> &list_J,
std::vector<Tindex> &list_k1_index,
std::vector<Tindex> &list_k2_index,
const bool flag_task_repeatable);
}

}
Expand Down
130 changes: 130 additions & 0 deletions include/RI/distribute/Distribute_Equally.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,136 @@ namespace Distribute_Equally
period);
return atoms_split_list;
}

// 均分{atomI,atomJ,k1,k2}
template<typename Tindex>
void distribute_atom_and_k_pair(
const MPI_Comm &mpi_comm,
const std::size_t nat,
const std::size_t nk,
std::vector<Tindex> &list_I,
std::vector<Tindex> &list_J,
std::vector<Tindex> &list_k1_index,
std::vector<Tindex> &list_k2_index,
const bool flag_task_repeatable)
{
// task_sizes的顺序必须从小到大,否则在split中会出现rank_size<group_size,所以先判断nat和nk的大小
std::size_t ntaskA, ntaskB;
std::vector<Tindex> *A1_ptr, *A2_ptr, *B1_ptr, *B2_ptr;
if (nk >= nat)
{
ntaskA = nat;
ntaskB = nk;
A1_ptr = &list_I;
A2_ptr = &list_J;
B1_ptr = &list_k1_index;
B2_ptr = &list_k2_index;
}
else
{
ntaskA = nk;
ntaskB = nat;
A1_ptr = &list_k1_index;
A2_ptr = &list_k2_index;
B1_ptr = &list_I;
B2_ptr = &list_J;
}
const std::vector<std::size_t> task_sizes{ntaskA, ntaskA, ntaskB, ntaskB};
const std::vector<std::tuple<MPI_Wrapper::mpi_comm, std::size_t, std::size_t>>
comm_color_sizes = Split_Processes::split_all(mpi_comm, task_sizes);

if(!flag_task_repeatable)
if(RI::MPI_Wrapper::mpi_get_rank(std::get<0>(comm_color_sizes.back())()))
return;

std::vector<Tindex> indicesA, indicesB;
for(Tindex i=0; i<ntaskA; ++i)
indicesA.push_back(i);
for(Tindex i=0; i<ntaskB; ++i)
indicesB.push_back(i);

*A1_ptr = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[1]),
std::get<2>(comm_color_sizes[1]),
indicesA);
*A2_ptr = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[2]),
std::get<2>(comm_color_sizes[2]),
indicesA);
*B1_ptr = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[3]),
std::get<2>(comm_color_sizes[3]),
indicesB);
*B2_ptr = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[4]),
std::get<2>(comm_color_sizes[4]),
indicesB);
}

// 均分{atomI,atomJ,k}
template<typename Tindex>
void distribute_atom_pair_and_k(
const MPI_Comm &mpi_comm,
const std::size_t nat,
const std::size_t nk,
std::vector<Tindex> &list_I,
std::vector<Tindex> &list_J,
std::vector<Tindex> &list_k_index,
const bool flag_task_repeatable)
{
std::vector<std::size_t> task_sizes;
std::vector<Tindex> indices_atom, indices_k;
for(Tindex i=0; i<nat; ++i)
indices_atom.push_back(i);
for(Tindex i=0; i<nk; ++i)
indices_k.push_back(i);
// task_sizes的顺序必须从小到大,否则在split中会出现rank_size<group_size,所以先判断nat和nk的大小
if (nk >= nat)
{
task_sizes = {nat, nat, nk};
}
else
{
task_sizes = {nk, nat, nat};
}
const std::vector<std::tuple<MPI_Wrapper::mpi_comm, std::size_t, std::size_t>>
comm_color_sizes = Split_Processes::split_all(mpi_comm, task_sizes);

if(!flag_task_repeatable)
if(RI::MPI_Wrapper::mpi_get_rank(std::get<0>(comm_color_sizes.back())()))
return;

if (nk >= nat)
{
list_I = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[1]),
std::get<2>(comm_color_sizes[1]),
indices_atom);
list_J = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[2]),
std::get<2>(comm_color_sizes[2]),
indices_atom);
list_k_index = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[3]),
std::get<2>(comm_color_sizes[3]),
indices_k);
}
else
{
list_k_index = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[1]),
std::get<2>(comm_color_sizes[1]),
indices_k);
list_I = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[2]),
std::get<2>(comm_color_sizes[2]),
indices_atom);
list_J = Divide_Atoms::divide_atoms(
std::get<1>(comm_color_sizes[3]),
std::get<2>(comm_color_sizes[3]),
indices_atom);
}
}
}

}
7 changes: 6 additions & 1 deletion include/RI/global/Array_Operator.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ namespace RI
namespace Array_Operator
{
template<typename T, std::size_t N>
extern std::array<T,N> operator%(const std::array<T,N> &v1, const std::array<T,N> &v2);
typename std::enable_if<std::is_integral<T>::value, std::array<T,N>>::type
operator%(const std::array<T,N> &v1, const std::array<T,N> &v2);

template<typename T, std::size_t N>
typename std::enable_if<std::is_floating_point<T>::value, std::array<T,N>>::type
operator%(const std::array<T,N> &v1, const std::array<T,N> &v2);

template<typename T, std::size_t N>
extern std::array<T,N> operator+(const std::array<T,N> &v1, const std::array<T,N> &v2);
Expand Down
21 changes: 20 additions & 1 deletion include/RI/global/Array_Operator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ namespace RI
namespace Array_Operator
{
template<typename T, std::size_t N>
std::array<T,N> operator%(const std::array<T,N> &v1, const std::array<T,N> &v2)
typename std::enable_if<std::is_integral<T>::value, std::array<T,N>>::type
operator%(const std::array<T,N> &v1, const std::array<T,N> &v2)
{
auto mod = [](const T i, const T n){ return (i%n+3*n/2)%n-n/2; }; // [-n/2,n/2]
// auto mod = [](const T i, const T n){ return (i%n+n)%n; }; // [0,n)
Expand All @@ -23,6 +24,24 @@ namespace Array_Operator
v[i] = mod(v1[i], v2[i]);
return v;
}
template<typename T, std::size_t N>
typename std::enable_if<std::is_floating_point<T>::value, std::array<T,N>>::type
operator%(const std::array<T,N> &v1, const std::array<T,N> &v2)
{
constexpr double epsilon = 1e-6;
auto mod_f = [&](T x, T period){ // [0, period)
T r = std::fmod(x, period);
if (std::abs(r) < epsilon) r = 0.0;
if (std::abs(r - period) < epsilon) r = 0.0;
if (r < 0) r += period;

return r;
};
std::array<T,N> v;
for(std::size_t i=0; i<N; ++i)
v[i] = mod_f(v1[i], v2[i]);
return v;
}

template<typename T, std::size_t N>
std::array<T,N> operator+(const std::array<T,N> &v1, const std::array<T,N> &v2)
Expand Down
28 changes: 28 additions & 0 deletions include/RI/global/Global_Func-1.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,34 @@ namespace Global_Func
return find( ptr->second, keys... );
}

// These helper functions are used to replace Global_Func::find,
// since the target is not Tensor<Tdata>, but another map.
template<class Map, class Key>
static inline const typename Map::mapped_type find_map(const Map& map, const Key& key)
{
const auto& it = map.find(key);
if (it != map.end()) return it->second;
return typename Map::mapped_type();
}

template<class Map, class Key1, class Key2>
static inline const typename Map::mapped_type::mapped_type find_map(
const Map& map, const Key1& key1, const Key2& key2)
{
using InnerMap = typename Map::mapped_type;
using Target = typename InnerMap::mapped_type;

const auto it1 = map.find(key1);
if (it1 != map.end())
{
const auto& inner = it1->second;
const auto it2 = inner.find(key2);
if (it2 != inner.end())
return it2->second;
}
return Target();
}

// in_set(3, {2,3,5,7})
// Peize Lin add 2022.05.26
template<typename T>
Expand Down
15 changes: 15 additions & 0 deletions include/RI/global/Global_Func-2.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ namespace Global_Func
typename std::enable_if<!Global_Func::is_complex<Tout>::value,int>::type =0>
Tout convert(const Tin &t)
{ return t.real(); }

template<
typename T,
typename std::enable_if<!Global_Func::is_complex<T>::value,int>::type =0>
inline T get_conj(const T& x)
{
return x;
}
template<
typename T,
typename std::enable_if< Global_Func::is_complex<T>::value,int>::type =0>
inline T get_conj(const T& x)
{
return std::conj(x);
}
}

}
12 changes: 12 additions & 0 deletions include/RI/global/Shape_Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ class Shape_Vector
for(auto ptr_in=v_in.begin(); ptr_in<v_in.end(); )
*(ptr_this++) = *(ptr_in++);
}
Shape_Vector(const std::vector<std::size_t>& v_in)
:size_(v_in.size())
{
assert(v_in.size() <= sizeof(v) / sizeof(*v));
for (std::size_t i = 0;i < size_;++i) this->v[i] = v_in[i];
}
Shape_Vector(std::vector<std::size_t>&& v_in)
:size_(v_in.size())
{
assert(v_in.size() <= sizeof(v) / sizeof(*v));
for (std::size_t i = 0;i < size_;++i) this->v[i] = v_in[i];
}

const std::size_t* begin() const noexcept { return this->v; }
const std::size_t* end() const noexcept { return this->v+size_; }
Expand Down
9 changes: 9 additions & 0 deletions include/RI/global/Tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ class Tensor

Tensor transpose() const;
Tensor dagger() const;
Tensor conjugate() const;

// get maximum absolute value among all elements
Global_Func::To_Real_t<T> max_abs() const;

/// permute from the input index order to {0, 1, 2, ..., N}
Tensor permute_from(const std::vector<std::size_t>& order) const;
/// permute from {0, 1, 2, ..., N } to the input new index order
// Tensor permute_to(const std::vector<std::size_t>) const;

// ||d||_p = (|d_1|^p+|d_2|^p+...)^{1/p}
// if(p==std::numeric_limits<double>::max()) ||d||_max = max_i |d_i|
Expand Down
Loading