Skip to content

Commit

Permalink
Merge branch 'master' into feature/model
Browse files Browse the repository at this point in the history
  • Loading branch information
David Williams-Young committed Jun 13, 2023
2 parents e0ef771 + 48f2ba0 commit 9ab4627
Show file tree
Hide file tree
Showing 32 changed files with 416 additions and 71 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/build_and_test_compiler_zoo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ jobs:
matrix:
compiler: [ {suite: gnu, version: 12} ]
openmp_flag: [ON, OFF]
mpi_flag: [ON, OFF]
exclude:
- compiler: {suite: llvm, version: 14}
openmp_flag: ON
- openmp_flag: OFF
mpi_flag: ON

steps:
- uses: actions/checkout@v3
Expand All @@ -33,6 +36,11 @@ jobs:
run: echo "set(MACIS_ENABLE_OPENMP ${{matrix.openmp_flag}} CACHE BOOL \"\" FORCE)" >>
${GITHUB_WORKSPACE}/${GH_ACTIONS_TOOLCHAIN}

- name: Enable or Disable MPI
shell: bash
run: echo "set(MACIS_ENABLE_MPI ${{matrix.mpi_flag}} CACHE BOOL \"\" FORCE)" >>
${GITHUB_WORKSPACE}/${GH_ACTIONS_TOOLCHAIN}

- name: Setup Build Type
shell: bash
run: echo "set(CMAKE_BUILD_TYPE Release CACHE BOOL \"\" FORCE)" >>
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ cmake_minimum_required(VERSION 3.14)
project(MACIS VERSION 0.1 LANGUAGES C CXX)


option( MACIS_ENABLE_MPI "Enable MPI Bindings" ON )
option( MACIS_ENABLE_OPENMP "Enable OpenMP Bindings" ON )
option( MACIS_ENABLE_BOOST "Enable Boost" ON )

Expand Down
5 changes: 4 additions & 1 deletion cmake/macis-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ get_filename_component( macis_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH )
#list( APPEND CMAKE_MODULE_PATH ${macis_CMAKE_DIR} )

set( MACIS_ENABLE_BOOST @MACIS_ENABLE_BOOST@ )
set( MACIS_ENABLE_MPI @MACIS_ENABLE_MPI@ )
set( MACIS_ENABLE_OPENMP @MACIS_ENABLE_OPENMP@ )

include( CMakeFindDependencyMacro )
find_dependency( MPI )
if( MACIS_ENABLE_MPI )
find_dependency( MPI )
endif()
if( MACIS_ENABLE_OPENMP )
find_dependency( OpenMP )
endif()
Expand Down
48 changes: 43 additions & 5 deletions include/macis/asci/determinant_search.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#pragma once
#include <spdlog/sinks/null_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>

Expand Down Expand Up @@ -139,6 +140,7 @@ asci_contrib_container<wfn_t<N>> asci_contributions_standard(
return asci_pairs;
}

#ifdef MACIS_ENABLE_MPI
template <size_t N>
asci_contrib_container<wfn_t<N>> asci_contributions_constraint(
ASCISettings asci_settings, wavefunction_iterator_t<N> cdets_begin,
Expand Down Expand Up @@ -387,6 +389,7 @@ asci_contrib_container<wfn_t<N>> asci_contributions_constraint(

return asci_pairs;
}
#endif

template <size_t N>
std::vector<wfn_t<N>> asci_search(
Expand All @@ -395,19 +398,26 @@ std::vector<wfn_t<N>> asci_search(
wavefunction_iterator_t<N> cdets_end, const double E_ASCI,
const std::vector<double>& C, size_t norb, const double* T_pq,
const double* G_red, const double* V_red, const double* G_pqrs,
const double* V_pqrs, HamiltonianGenerator<N>& ham_gen, MPI_Comm comm) {
const double* V_pqrs,
HamiltonianGenerator<N>& ham_gen MACIS_MPI_CODE(, MPI_Comm comm)) {
using clock_type = std::chrono::high_resolution_clock;
using duration_type = std::chrono::duration<double>;

// MPI Info
#ifdef MACIS_ENABLE_MPI
auto world_rank = comm_rank(comm);
auto world_size = comm_size(comm);
#else
int world_rank = 0;
int world_size = 1;
#endif

auto logger = spdlog::get("asci_search");
if(!logger)
logger = world_rank ? spdlog::null_logger_mt("asci_search")
: spdlog::stdout_color_mt("asci_search");

#ifdef MACIS_ENABLE_MPI
auto print_mpi_stats = [&](auto str, auto vmin, auto vmax, auto vavg) {
std::string fmt_string =
" * {0}_MIN = {1}, {0}_MAX = {2}, {0}_AVG = {3}, RATIO = {4:.2e}";
Expand All @@ -417,6 +427,7 @@ std::vector<wfn_t<N>> asci_search(
"RATIO = {4:.2e}";
logger->info(fmt_string, str, vmin, vmax, vavg, vmax / float(vmin));
};
#endif

// Print Search Header to logger
const size_t ncdets = std::distance(cdets_begin, cdets_end);
Expand All @@ -427,7 +438,7 @@ std::vector<wfn_t<N>> asci_search(
logger->info(" MAX_RV_SIZE = {}, JUST_SINGLES = {}",
asci_settings.pair_size_max, asci_settings.just_singles);

MPI_Barrier(comm);
MACIS_MPI_CODE(MPI_Barrier(comm);)
auto asci_search_st = clock_type::now();

// Expand Search Space with Connected ASCI Contributions
Expand All @@ -437,30 +448,40 @@ std::vector<wfn_t<N>> asci_search(
asci_pairs = asci_contributions_standard(
asci_settings, cdets_begin, cdets_end, E_ASCI, C, norb, T_pq, G_red,
V_red, G_pqrs, V_pqrs, ham_gen);
#ifdef MACIS_ENABLE_MPI
else
asci_pairs = asci_contributions_constraint(
asci_settings, cdets_begin, cdets_end, E_ASCI, C, norb, T_pq, G_red,
V_red, G_pqrs, V_pqrs, ham_gen, comm);
V_red, G_pqrs, V_pqrs, ham_gen MACIS_MPI_CODE(, comm));
#endif
auto pairs_en = clock_type::now();

{
#ifdef MACIS_ENABLE_MPI
size_t npairs = allreduce(asci_pairs.size(), MPI_SUM, comm);
#else
size_t npairs = asci_pairs.size();
#endif
logger->info(" * ASCI Kept {} Pairs", npairs);

#ifdef MACIS_ENABLE_MPI
if(world_size > 1) {
size_t npairs_max = allreduce(asci_pairs.size(), MPI_MAX, comm);
size_t npairs_min = allreduce(asci_pairs.size(), MPI_MIN, comm);
print_mpi_stats("PAIRS_LOC", npairs_min, npairs_max, npairs / world_size);
}
#endif

if(world_size == 1) {
logger->info(" * Pairs Mem = {:.2e} GiB", to_gib(asci_pairs));
} else {
#ifdef MACIS_ENABLE_MPI
float local_mem = to_gib(asci_pairs);
float total_mem = allreduce(local_mem, MPI_SUM, comm);
float min_mem = allreduce(local_mem, MPI_MIN, comm);
float max_mem = allreduce(local_mem, MPI_MAX, comm);
print_mpi_stats("PAIRS_MEM", min_mem, max_mem, total_mem / world_size);
#endif
}
}

Expand All @@ -478,21 +499,26 @@ std::vector<wfn_t<N>> asci_search(
auto bit_sort_en = clock_type::now();

{
#ifdef MACIS_ENABLE_MPI
size_t npairs = allreduce(asci_pairs.size(), MPI_SUM, comm);
;
#else
size_t npairs = asci_pairs.size();
#endif
logger->info(" * ASCI will search over {} unique determinants", npairs);

float pairs_dur = duration_type(pairs_en - pairs_st).count();
float bit_sort_dur = duration_type(bit_sort_en - bit_sort_st).count();

if(world_size > 1) {
#ifdef MACIS_ENABLE_MPI
float timings = pairs_dur;
float timings_max, timings_min, timings_avg;
allreduce(&timings, &timings_max, 1, MPI_MAX, comm);
allreduce(&timings, &timings_min, 1, MPI_MIN, comm);
allreduce(&timings, &timings_avg, 1, MPI_SUM, comm);
timings_avg /= world_size;
print_mpi_stats("PAIRS_DUR", timings_min, timings_max, timings_avg);
#endif
} else {
logger->info(" * PAIR_DUR = {:.2e} s, SORT_ACC_DUR = {:.2e} s",
pairs_dur, bit_sort_dur);
Expand Down Expand Up @@ -523,11 +549,13 @@ std::vector<wfn_t<N>> asci_search(
auto keep_large_en = clock_type::now();
duration_type keep_large_dur = keep_large_en - keep_large_st;
if(world_size > 1) {
#ifdef MACIS_ENABLE_MPI
float dur = keep_large_dur.count();
auto dmin = allreduce(dur, MPI_MIN, comm);
auto dmax = allreduce(dur, MPI_MAX, comm);
auto davg = allreduce(dur, MPI_SUM, comm) / world_size;
print_mpi_stats("KEEP_LARG_DUR", dmin, dmax, davg);
#endif
} else {
logger->info(" * KEEP_LARG_DUR = {:.2e} s", keep_large_dur.count());
}
Expand All @@ -537,6 +565,7 @@ std::vector<wfn_t<N>> asci_search(
if(world_size > 1 or asci_pairs.size() > top_k_elements) {
std::vector<asci_contrib<wfn_t<N>>> topk(top_k_elements);
if(world_size > 1) {
#ifdef MACIS_ENABLE_MPI
// Strip scores
std::vector<double> scores(asci_pairs.size());
std::transform(asci_pairs.begin(), asci_pairs.end(), scores.begin(),
Expand Down Expand Up @@ -575,13 +604,20 @@ std::vector<wfn_t<N>> asci_search(
keep_strings_global.data(), local_sizes.data(),
displ.data(), string_dtype, comm);

// Edge case where NGEQ > TOPK - erase equivalent elements
if(n_geq_global > top_k_elements) {
n_geq_global = top_k_elements;
keep_strings_global.resize(n_geq_global);
}

// Make fake strings
topk.resize(n_geq_global);
std::transform(keep_strings_global.begin(), keep_strings_global.end(),
topk.begin(), [](const auto& s) {
return asci_contrib<wfn_t<N>>{s, -1.0};
});

#endif
} else {
std::nth_element(asci_pairs.begin(), asci_pairs.begin() + top_k_elements,
asci_pairs.end(),
Expand All @@ -593,11 +629,13 @@ std::vector<wfn_t<N>> asci_search(
}
auto asci_sort_en = clock_type::now();
if(world_size > 1) {
#ifdef MACIS_ENABLE_MPI
float dur = duration_type(asci_sort_en - asci_sort_st).count();
auto dmin = allreduce(dur, MPI_MIN, comm);
auto dmax = allreduce(dur, MPI_MAX, comm);
auto davg = allreduce(dur, MPI_SUM, comm) / world_size;
print_mpi_stats("ASCI_SORT_DUR", dmin, dmax, davg);
#endif
} else {
logger->info(" * ASCI_SORT_DUR = {:.2e} s",
duration_type(asci_sort_en - asci_sort_st).count());
Expand All @@ -617,7 +655,7 @@ std::vector<wfn_t<N>> asci_search(

logger->info(" * New Dets Mem = {:.2e} GiB", to_gib(new_dets));

MPI_Barrier(comm);
MACIS_MPI_CODE(MPI_Barrier(comm);)
auto asci_search_en = clock_type::now();
duration_type asci_search_dur = asci_search_en - asci_search_st;
logger->info(" * ASCI_SEARCH DUR = {:.2e} s", asci_search_dur.count());
Expand Down
22 changes: 16 additions & 6 deletions include/macis/asci/grow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ namespace macis {
template <size_t N, typename index_t = int32_t>
auto asci_grow(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
double E0, std::vector<wfn_t<N>> wfn, std::vector<double> X,
HamiltonianGenerator<N>& ham_gen, size_t norb, MPI_Comm comm) {
HamiltonianGenerator<N>& ham_gen,
size_t norb MACIS_MPI_CODE(, MPI_Comm comm)) {
#ifdef MACIS_ENABLE_MPI
auto world_rank = comm_rank(comm);
auto world_size = comm_size(comm);
#else
auto world_rank = 0;
auto world_size = 1;
#endif

using hrt_t = std::chrono::high_resolution_clock;
using dur_t = std::chrono::duration<double, std::milli>;
Expand Down Expand Up @@ -50,7 +56,7 @@ auto asci_grow(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
auto ai_st = hrt_t::now();
std::tie(E, wfn, X) = asci_iter<N, index_t>(
asci_settings, mcscf_settings, ndets_new, E0, std::move(wfn),
std::move(X), ham_gen, norb, comm);
std::move(X), ham_gen, norb MACIS_MPI_CODE(, comm));
auto ai_en = hrt_t::now();
dur_t ai_dur = ai_en - ai_st;
logger->trace(" * ASCI_ITER_DUR = {:.2e} ms", ai_dur.count());
Expand Down Expand Up @@ -105,23 +111,26 @@ auto asci_grow(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
}

// Broadcast rotated integrals
#ifdef MACIS_ENABLE_MPI
if(world_size > 1) {
bcast(ham_gen.T(), norb * norb, 0, comm);
bcast(ham_gen.V(), norb * norb * norb * norb, 0, comm);
}
#endif

// Regenerate intermediates
ham_gen.generate_integral_intermediates(ham_gen.V_pqrs_);

logger->trace(" * Rediagonalizing");
auto rdg_st = hrt_t::now();
std::vector<double> X_local;
selected_ci_diag(wfn.begin(), wfn.end(), ham_gen,
mcscf_settings.ci_matel_tol,
mcscf_settings.ci_max_subspace,
mcscf_settings.ci_res_tol, X_local, comm);
selected_ci_diag(
wfn.begin(), wfn.end(), ham_gen, mcscf_settings.ci_matel_tol,
mcscf_settings.ci_max_subspace, mcscf_settings.ci_res_tol,
X_local MACIS_MPI_CODE(, comm));

if(world_size > 1) {
#ifdef MACIS_ENABLE_MPI
// Broadcast X_local to X
const size_t wfn_size = wfn.size();
const size_t local_count = wfn_size / world_size;
Expand All @@ -138,6 +147,7 @@ auto asci_grow(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
}
MPI_Bcast(X_rem, nrem, MPI_DOUBLE, world_size - 1, comm);
}
#endif
} else {
// Avoid copy
X = std::move(X_local);
Expand Down
11 changes: 8 additions & 3 deletions include/macis/asci/iteration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ template <size_t N, typename index_t = int32_t>
auto asci_iter(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
size_t ndets_max, double E0, std::vector<wfn_t<N>> wfn,
std::vector<double> X, HamiltonianGenerator<N>& ham_gen,
size_t norb, MPI_Comm comm) {
size_t norb MACIS_MPI_CODE(, MPI_Comm comm)) {
// Sort wfn on coefficient weights
if(wfn.size() > 1) reorder_ci_on_coeff(wfn, X);

Expand All @@ -27,14 +27,16 @@ auto asci_iter(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
// Perform the ASCI search
wfn = asci_search(asci_settings, ndets_max, wfn.begin(), wfn.begin() + nkeep,
E0, X, norb, ham_gen.T(), ham_gen.G_red(), ham_gen.V_red(),
ham_gen.G(), ham_gen.V(), ham_gen, comm);
ham_gen.G(), ham_gen.V(), ham_gen MACIS_MPI_CODE(, comm));

// Rediagonalize
std::vector<double> X_local; // Precludes guess reuse
auto E = selected_ci_diag<N, index_t>(
wfn.begin(), wfn.end(), ham_gen, mcscf_settings.ci_matel_tol,
mcscf_settings.ci_max_subspace, mcscf_settings.ci_res_tol, X_local, comm);
mcscf_settings.ci_max_subspace, mcscf_settings.ci_res_tol,
X_local MACIS_MPI_CODE(, comm));

#ifdef MACIS_ENABLE_MPI
auto world_size = comm_size(comm);
auto world_rank = comm_rank(comm);
if(world_size > 1) {
Expand All @@ -58,6 +60,9 @@ auto asci_iter(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
// Avoid copy
X = std::move(X_local);
}
#else
X = std::move(X_local); // Serial
#endif

return std::make_tuple(E, wfn, X);
}
Expand Down
2 changes: 2 additions & 0 deletions include/macis/asci/mask_constraints.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ auto dist_triplets_histogram(size_t norb, size_t ns_othr, size_t nd_othr,
}
#endif

#ifdef MACIS_ENABLE_MPI
template <size_t N>
auto dist_constraint_general(size_t nlevels, size_t norb, size_t ns_othr,
size_t nd_othr,
Expand Down Expand Up @@ -599,6 +600,7 @@ auto dist_constraint_general(size_t nlevels, size_t norb, size_t ns_othr,

return constraints;
}
#endif

#if 0
template <typename Integral, size_t N>
Expand Down
9 changes: 7 additions & 2 deletions include/macis/asci/refine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ namespace macis {
template <size_t N, typename index_t = int32_t>
auto asci_refine(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
double E0, std::vector<wfn_t<N>> wfn, std::vector<double> X,
HamiltonianGenerator<N>& ham_gen, size_t norb, MPI_Comm comm) {
HamiltonianGenerator<N>& ham_gen,
size_t norb MACIS_MPI_CODE(, MPI_Comm comm)) {
auto logger = spdlog::get("asci_refine");
#ifdef MACIS_ENABLE_MPI
auto world_rank = comm_rank(comm);
#else
int world_rank = 0;
#endif
if(!logger)
logger = world_rank ? spdlog::null_logger_mt("asci_refine")
: spdlog::stdout_color_mt("asci_refine");
Expand All @@ -39,7 +44,7 @@ auto asci_refine(ASCISettings asci_settings, MCSCFSettings mcscf_settings,
double E;
std::tie(E, wfn, X) = asci_iter<N, index_t>(
asci_settings, mcscf_settings, ndets, E0, std::move(wfn), std::move(X),
ham_gen, norb, comm);
ham_gen, norb MACIS_MPI_CODE(, comm));
if(wfn.size() != ndets)
throw std::runtime_error("Wavefunction size can't change in refinement");

Expand Down
Loading

0 comments on commit 9ab4627

Please sign in to comment.