Loading CMakeLists.txt +11 −5 Original line number Diff line number Diff line Loading @@ -174,6 +174,8 @@ separate_arguments(MPIEXEC_PREFLAGS UNIX_COMMAND ${MPIEXEC_PREFLAGS}) set(gtest_dir "${PROJECT_SOURCE_DIR}/libs/googletest-1.8.0" CACHE PATH "Path to Google Test.") mark_as_advanced(gtest_dir) set(benchmark_dir "${PROJECT_SOURCE_DIR}/libs/benchmark" CACHE PATH "Path to Google Benchmark.") mark_as_advanced(benchmark_dir) if (DCA_WITH_TESTS_FAST OR DCA_WITH_TESTS_EXTENSIVE OR DCA_WITH_TESTS_STOCHASTIC OR DCA_WITH_TESTS_PERFORMANCE) Loading @@ -186,16 +188,20 @@ if (DCA_WITH_TESTS_FAST OR DCA_WITH_TESTS_EXTENSIVE OR DCA_WITH_TESTS_STOCHASTI message(WARNING "Tests are built with NDEBUG defined!") endif() if (DCA_WITH_TESTS_PERFORMANCE AND NOT (CMAKE_BUILD_TYPE STREQUAL "Release")) set(BENCHMARK_ENABLE_TESTING OFF) add_subdirectory(${gtest_dir}) add_subdirectory(${PROJECT_SOURCE_DIR}/test) if (DCA_WITH_TESTS_PERFORMANCE) if(NOT (CMAKE_BUILD_TYPE STREQUAL "Release")) message(WARNING "Performance tests are only built in release mode.") endif() add_subdirectory(${benchmark_dir}) endif() if (DCA_HAVE_MPI AND (TEST_RUNNER STREQUAL "")) message(FATAL_ERROR "TEST_RUNNER needs to be set to the command for executing MPI programs, e.g. mpiexec, mpirun, aprun or srun.") endif() add_subdirectory(${gtest_dir}) add_subdirectory(${PROJECT_SOURCE_DIR}/test) endif() ################################################################################ Loading cmake/dca_testing.cmake +31 −0 Original line number Diff line number Diff line ################################################################################ # Author: Urs R. Haehner (haehneru@itp.phys.ethz.ch) # Giovanni Balduzzi (gbalduzz@itp.phys.ethz.ch) # # Enables testing. # References: - https://github.com/ALPSCore/ALPSCore Loading Loading @@ -140,3 +141,33 @@ function(dca_add_gtest name) endif() endfunction() # Adds a performance test written with the Google benchmark. # # dca_add_gtest(name # [INCLUDE_DIRS dir1 [dir2 ...]] # [LIBS lib1 [lib2 ...]]) # # If DCA_WITH_TESTS_PERFORMANCE is defined, adds a test called 'name', the source is assumed to be # 'name.cpp'. function(dca_add_perftest name) set(multiValueArgs INCLUDE_DIRS LIBS) cmake_parse_arguments(DCA_ADD_GTEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if (NOT DCA_WITH_TESTS_PERFORMANCE) return() endif() add_executable(${name} ${name}.cpp) target_include_directories(${name} PRIVATE ${benchmark_dir}/include ${PROJECT_SOURCE_DIR}/include ${DCA_ADD_PERFTEST_INCLUDE_DIRS}) target_link_libraries(${name} PRIVATE ${DCA_ADD_PERFTEST_LIBS};gtest benchmark_main benchmark) target_compile_definitions(${name} PRIVATE DCA_SOURCE_DIR=\"${PROJECT_SOURCE_DIR}\") endfunction() include/dca/phys/dca_step/cluster_solver/ctint/structs/solver_configuration.hpp +13 −63 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "dca/phys/dca_step/cluster_solver/ctint/structs/interaction_vertices.hpp" #include "dca/phys/dca_step/cluster_solver/ctint/structs/utils.hpp" #include "dca/linalg/device_type.hpp" #include "dca/util/containers/random_access_map.hpp" namespace dca { namespace phys { Loading Loading @@ -50,11 +51,12 @@ public: void insertRandom(RngType& rng); // Returns the indices of the removal candidates. -1 stands for a missing candidate. template <class RngType> std::array<int, 2> randomRemovalCandidate(RngType& rng); // Similar to the above method, but sample vertices irrespective of their order. std::array<int, 2> randomRemovalCandidateSlow(const std::array<double, 3>& rng_vals); std::array<int, 2> randomRemovalCandidate(const std::array<double, 3>& rvals); // Similar to the method above. // Precondition: no double moves are proposed. std::array<int, 2> randomRemovalCandidate(double rval) { return randomRemovalCandidate({rval, -1, -1}); } // Out: indices. Appends the result of the search to indices. template <class Alloc> Loading Loading @@ -130,16 +132,17 @@ private: std::array<std::vector<ConfigRef>, 2> matrix_config_indices_; using BaseClass::H_int_; std::vector<std::vector<std::size_t>> existing_; // TODO: use a structure with fast (log N?) removal/insertion and random access. // Or sample randomly from std::unordered_set using its hash function, if it's good enough. std::vector<const std::vector<std::size_t>*> partners_lists_; std::vector<details::VertexTypeList> existing_; // Temporary storage for the removal candidate method. std::vector<const details::VertexTypeList*> partners_lists_; unsigned short last_insertion_size_ = 1; const double max_tau_ = 0; const int n_bands_ = 0; unsigned n_annihilatable_ = 0; dca::util::RandomAccessMap<std::size_t, unsigned> anhilatable_indices_; std::uint64_t current_tag_ = 0; }; Loading @@ -165,59 +168,6 @@ void SolverConfiguration::insertRandom(Rng& rng) { assert(2 * size() == getSector(0).size() + getSector(1).size()); } template <class RngType> std::array<int, 2> SolverConfiguration::randomRemovalCandidate(RngType& rng) { std::array<int, 2> candidates{-1, -1}; if (n_annihilatable_ == 0) return candidates; // Note: // When sampling by retrying in case of failure, the probability of success is p_s n / // n_annihlatable, with n = size(). This translates to an expected cost of \sum_l l p_s (1 - // p_s)^(l - 1) = 1 / p_s. Therefore this algorithm is faster than a read on all the // vertices when n_annihlatable > cost(random _number) / cost(vertex_read). // Lets assume cost(random _number) / cost(vertex_read) =~ 10 // This also helps when testing on a small configuration as we need only one random number. constexpr unsigned threshold = 10; if (n_annihilatable_ >= threshold) { do { candidates[0] = rng() * size(); } while (!vertices_[candidates[0]].annihilatable); } else { unsigned annihilatable_idx = rng() * n_annihilatable_; unsigned annihilatable_found = 0; for (int i = 0; i < vertices_.size(); ++i) { if (vertices_[i].annihilatable) { if (annihilatable_found == annihilatable_idx) { candidates[0] = i; break; } ++annihilatable_found; } } } if (doDoubleUpdate(rng) && (*H_int_)[vertices_[candidates[0]].interaction_id].partners_id.size()) { // Double removal. partners_lists_.clear(); for (const auto& partner_id : (*H_int_)[vertices_[candidates[0]].interaction_id].partners_id) partners_lists_.push_back(&existing_[partner_id]); const auto tag = details::getRandomElement(partners_lists_, rng()); if (tag != -1) { candidates[1] = findTag(tag); assert(candidates[1] < int(size()) && candidates[1] >= 0); assert(vertices_[candidates[1]].annihilatable); } } assert(candidates[0] < int(size())); return candidates; } // namespace ctint template <class Rng> bool SolverConfiguration::doDoubleUpdate(Rng& rng) const { if (double_insertion_prob_ == 0) Loading include/dca/phys/dca_step/cluster_solver/ctint/structs/utils.hpp +6 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ #include <stdexcept> #include <vector> #include "dca/util/containers/random_access_set.hpp" namespace dca { namespace phys { namespace solver { Loading @@ -22,8 +24,10 @@ namespace ctint { namespace details { // dca::phys::solver::ctint::details:: unsigned getRandomElement(const std::vector<const std::vector<std::size_t>*>& v_ptrs, const double rand) noexcept; using VertexTypeList = dca::util::RandomAccessSet<std::size_t, 16>; std::size_t getRandomElement(const std::vector<const VertexTypeList*>& v_ptrs, double rand) noexcept; } // namespace details } // namespace ctint Loading include/dca/phys/dca_step/cluster_solver/ctint/walker/ctint_walker_choice.hpp +2 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ struct CtintWalkerChoicheSelector; template <class Parameters, typename Real> struct CtintWalkerChoicheSelector<linalg::CPU, Parameters, true, Real> { using type = CtintWalkerSubmatrixCpu<Parameters, Real, false>; using type = CtintWalkerSubmatrixCpu<Parameters, Real>; }; template <class Parameters, typename Real> struct CtintWalkerChoicheSelector<linalg::CPU, Parameters, false, Real> { Loading @@ -41,7 +41,7 @@ struct CtintWalkerChoicheSelector<linalg::CPU, Parameters, false, Real> { #ifdef DCA_HAVE_CUDA template <class Parameters, typename Real> struct CtintWalkerChoicheSelector<linalg::GPU, Parameters, true, Real> { using type = CtintWalkerSubmatrixGpu<Parameters, Real, false>; using type = CtintWalkerSubmatrixGpu<Parameters, Real>; }; template <class Parameters, typename Real> Loading Loading
CMakeLists.txt +11 −5 Original line number Diff line number Diff line Loading @@ -174,6 +174,8 @@ separate_arguments(MPIEXEC_PREFLAGS UNIX_COMMAND ${MPIEXEC_PREFLAGS}) set(gtest_dir "${PROJECT_SOURCE_DIR}/libs/googletest-1.8.0" CACHE PATH "Path to Google Test.") mark_as_advanced(gtest_dir) set(benchmark_dir "${PROJECT_SOURCE_DIR}/libs/benchmark" CACHE PATH "Path to Google Benchmark.") mark_as_advanced(benchmark_dir) if (DCA_WITH_TESTS_FAST OR DCA_WITH_TESTS_EXTENSIVE OR DCA_WITH_TESTS_STOCHASTIC OR DCA_WITH_TESTS_PERFORMANCE) Loading @@ -186,16 +188,20 @@ if (DCA_WITH_TESTS_FAST OR DCA_WITH_TESTS_EXTENSIVE OR DCA_WITH_TESTS_STOCHASTI message(WARNING "Tests are built with NDEBUG defined!") endif() if (DCA_WITH_TESTS_PERFORMANCE AND NOT (CMAKE_BUILD_TYPE STREQUAL "Release")) set(BENCHMARK_ENABLE_TESTING OFF) add_subdirectory(${gtest_dir}) add_subdirectory(${PROJECT_SOURCE_DIR}/test) if (DCA_WITH_TESTS_PERFORMANCE) if(NOT (CMAKE_BUILD_TYPE STREQUAL "Release")) message(WARNING "Performance tests are only built in release mode.") endif() add_subdirectory(${benchmark_dir}) endif() if (DCA_HAVE_MPI AND (TEST_RUNNER STREQUAL "")) message(FATAL_ERROR "TEST_RUNNER needs to be set to the command for executing MPI programs, e.g. mpiexec, mpirun, aprun or srun.") endif() add_subdirectory(${gtest_dir}) add_subdirectory(${PROJECT_SOURCE_DIR}/test) endif() ################################################################################ Loading
cmake/dca_testing.cmake +31 −0 Original line number Diff line number Diff line ################################################################################ # Author: Urs R. Haehner (haehneru@itp.phys.ethz.ch) # Giovanni Balduzzi (gbalduzz@itp.phys.ethz.ch) # # Enables testing. # References: - https://github.com/ALPSCore/ALPSCore Loading Loading @@ -140,3 +141,33 @@ function(dca_add_gtest name) endif() endfunction() # Adds a performance test written with the Google benchmark. # # dca_add_gtest(name # [INCLUDE_DIRS dir1 [dir2 ...]] # [LIBS lib1 [lib2 ...]]) # # If DCA_WITH_TESTS_PERFORMANCE is defined, adds a test called 'name', the source is assumed to be # 'name.cpp'. function(dca_add_perftest name) set(multiValueArgs INCLUDE_DIRS LIBS) cmake_parse_arguments(DCA_ADD_GTEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if (NOT DCA_WITH_TESTS_PERFORMANCE) return() endif() add_executable(${name} ${name}.cpp) target_include_directories(${name} PRIVATE ${benchmark_dir}/include ${PROJECT_SOURCE_DIR}/include ${DCA_ADD_PERFTEST_INCLUDE_DIRS}) target_link_libraries(${name} PRIVATE ${DCA_ADD_PERFTEST_LIBS};gtest benchmark_main benchmark) target_compile_definitions(${name} PRIVATE DCA_SOURCE_DIR=\"${PROJECT_SOURCE_DIR}\") endfunction()
include/dca/phys/dca_step/cluster_solver/ctint/structs/solver_configuration.hpp +13 −63 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "dca/phys/dca_step/cluster_solver/ctint/structs/interaction_vertices.hpp" #include "dca/phys/dca_step/cluster_solver/ctint/structs/utils.hpp" #include "dca/linalg/device_type.hpp" #include "dca/util/containers/random_access_map.hpp" namespace dca { namespace phys { Loading Loading @@ -50,11 +51,12 @@ public: void insertRandom(RngType& rng); // Returns the indices of the removal candidates. -1 stands for a missing candidate. template <class RngType> std::array<int, 2> randomRemovalCandidate(RngType& rng); // Similar to the above method, but sample vertices irrespective of their order. std::array<int, 2> randomRemovalCandidateSlow(const std::array<double, 3>& rng_vals); std::array<int, 2> randomRemovalCandidate(const std::array<double, 3>& rvals); // Similar to the method above. // Precondition: no double moves are proposed. std::array<int, 2> randomRemovalCandidate(double rval) { return randomRemovalCandidate({rval, -1, -1}); } // Out: indices. Appends the result of the search to indices. template <class Alloc> Loading Loading @@ -130,16 +132,17 @@ private: std::array<std::vector<ConfigRef>, 2> matrix_config_indices_; using BaseClass::H_int_; std::vector<std::vector<std::size_t>> existing_; // TODO: use a structure with fast (log N?) removal/insertion and random access. // Or sample randomly from std::unordered_set using its hash function, if it's good enough. std::vector<const std::vector<std::size_t>*> partners_lists_; std::vector<details::VertexTypeList> existing_; // Temporary storage for the removal candidate method. std::vector<const details::VertexTypeList*> partners_lists_; unsigned short last_insertion_size_ = 1; const double max_tau_ = 0; const int n_bands_ = 0; unsigned n_annihilatable_ = 0; dca::util::RandomAccessMap<std::size_t, unsigned> anhilatable_indices_; std::uint64_t current_tag_ = 0; }; Loading @@ -165,59 +168,6 @@ void SolverConfiguration::insertRandom(Rng& rng) { assert(2 * size() == getSector(0).size() + getSector(1).size()); } template <class RngType> std::array<int, 2> SolverConfiguration::randomRemovalCandidate(RngType& rng) { std::array<int, 2> candidates{-1, -1}; if (n_annihilatable_ == 0) return candidates; // Note: // When sampling by retrying in case of failure, the probability of success is p_s n / // n_annihlatable, with n = size(). This translates to an expected cost of \sum_l l p_s (1 - // p_s)^(l - 1) = 1 / p_s. Therefore this algorithm is faster than a read on all the // vertices when n_annihlatable > cost(random _number) / cost(vertex_read). // Lets assume cost(random _number) / cost(vertex_read) =~ 10 // This also helps when testing on a small configuration as we need only one random number. constexpr unsigned threshold = 10; if (n_annihilatable_ >= threshold) { do { candidates[0] = rng() * size(); } while (!vertices_[candidates[0]].annihilatable); } else { unsigned annihilatable_idx = rng() * n_annihilatable_; unsigned annihilatable_found = 0; for (int i = 0; i < vertices_.size(); ++i) { if (vertices_[i].annihilatable) { if (annihilatable_found == annihilatable_idx) { candidates[0] = i; break; } ++annihilatable_found; } } } if (doDoubleUpdate(rng) && (*H_int_)[vertices_[candidates[0]].interaction_id].partners_id.size()) { // Double removal. partners_lists_.clear(); for (const auto& partner_id : (*H_int_)[vertices_[candidates[0]].interaction_id].partners_id) partners_lists_.push_back(&existing_[partner_id]); const auto tag = details::getRandomElement(partners_lists_, rng()); if (tag != -1) { candidates[1] = findTag(tag); assert(candidates[1] < int(size()) && candidates[1] >= 0); assert(vertices_[candidates[1]].annihilatable); } } assert(candidates[0] < int(size())); return candidates; } // namespace ctint template <class Rng> bool SolverConfiguration::doDoubleUpdate(Rng& rng) const { if (double_insertion_prob_ == 0) Loading
include/dca/phys/dca_step/cluster_solver/ctint/structs/utils.hpp +6 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ #include <stdexcept> #include <vector> #include "dca/util/containers/random_access_set.hpp" namespace dca { namespace phys { namespace solver { Loading @@ -22,8 +24,10 @@ namespace ctint { namespace details { // dca::phys::solver::ctint::details:: unsigned getRandomElement(const std::vector<const std::vector<std::size_t>*>& v_ptrs, const double rand) noexcept; using VertexTypeList = dca::util::RandomAccessSet<std::size_t, 16>; std::size_t getRandomElement(const std::vector<const VertexTypeList*>& v_ptrs, double rand) noexcept; } // namespace details } // namespace ctint Loading
include/dca/phys/dca_step/cluster_solver/ctint/walker/ctint_walker_choice.hpp +2 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ struct CtintWalkerChoicheSelector; template <class Parameters, typename Real> struct CtintWalkerChoicheSelector<linalg::CPU, Parameters, true, Real> { using type = CtintWalkerSubmatrixCpu<Parameters, Real, false>; using type = CtintWalkerSubmatrixCpu<Parameters, Real>; }; template <class Parameters, typename Real> struct CtintWalkerChoicheSelector<linalg::CPU, Parameters, false, Real> { Loading @@ -41,7 +41,7 @@ struct CtintWalkerChoicheSelector<linalg::CPU, Parameters, false, Real> { #ifdef DCA_HAVE_CUDA template <class Parameters, typename Real> struct CtintWalkerChoicheSelector<linalg::GPU, Parameters, true, Real> { using type = CtintWalkerSubmatrixGpu<Parameters, Real, false>; using type = CtintWalkerSubmatrixGpu<Parameters, Real>; }; template <class Parameters, typename Real> Loading