From 3fda8acf8b4aefa0495dd948986bebbf076bc7fd Mon Sep 17 00:00:00 2001 From: Peter Doak Date: Mon, 10 Jun 2019 12:04:15 -0400 Subject: [PATCH 1/5] Abstraction for same task on N threads --- src/Utilities/ParallelBlock.hpp | 136 ++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/Utilities/ParallelBlock.hpp diff --git a/src/Utilities/ParallelBlock.hpp b/src/Utilities/ParallelBlock.hpp new file mode 100644 index 000000000..766919213 --- /dev/null +++ b/src/Utilities/ParallelBlock.hpp @@ -0,0 +1,136 @@ +//////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source +// License. See LICENSE file in top directory for details. +// +// Copyright (c) 2019 QMCPACK developers. +// +// File developed by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File created by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +//////////////////////////////////////////////////////////////////////////////// + +#ifndef QMCPLUSPLUS_PARALLELBLOCK_HPP +#define QMCPLUSPLUS_PARALLELBLOCK_HPP + +#include +#include + +namespace qmcplusplus +{ +template +class TaskWrapper +{ + F f; + template + void operator()(T&&... args) + { + f(std::forward(args)...); + } +}; + +enum class ParallelBlockThreading +{ + OPENMP, + STD + // Planned + // Boost + // hpx +}; + +/** Blocks until entire parallel block is done + * + * Required to prevent end of QMC block synchronization occuring + * before all crowds are complete. For Devices with global or partially global + * synchronization on memory management operations. RAII deallocation + * badly damage performance. + */ +template +class ParallelBlockBarrier +{ +public: + ParallelBlockBarrier(unsigned int num_threads) : num_threads_(num_threads) {} + void wait(); + +private: + unsigned int num_threads_; +}; + +template +inline void ParallelBlockBarrier::wait() +{ + std::cout << "At omp barrier\n"; +#pragma omp barrier +} + +template<> +inline void ParallelBlockBarrier::wait() +{ + std::cout << "Barrier not supported by std threading. Implementation needed to avoid performance hit at end of QMCBlock.\n"; +} + + +/** Simple abstraction to launch num_threads running the same task + * + * All run the same task and get the same arg set plus an "id" from 0 to num_threads - 1 + */ +template +class ParallelBlock +{ +public: + ParallelBlock(unsigned int num_threads) : num_threads_(num_threads) {} + template + void operator()(F&& f, Args&&... args); + template + void operator()(F&& f, ParallelBlockBarrier& barrier, Args&&... args); + +private: + unsigned int num_threads_; +}; + +template +template +void ParallelBlock::operator()(F&& f, Args&&... args) + +{ +#pragma omp parallel for + for (int task_id = 0; task_id < num_threads_; ++task_id) + { + f(task_id, std::forward(args)...); + } +} + +template +template +void ParallelBlock::operator()(F&& f, ParallelBlockBarrier& barrier, Args&&... args) + +{ + omp_set_num_threads(num_threads_); +#pragma omp parallel for + for (int task_id = 0; task_id < num_threads_; ++task_id) + { + f(task_id, barrier, std::forward(args)...); + } +} + +template<> +template +void ParallelBlock::operator()(F&& f, Args&&... args) + +{ + std::vector threads(num_threads_); + + for (int task_id = 0; task_id < num_threads_; ++task_id) + { + threads[task_id] = std::thread(TaskWrapper{std::forward(f)}, task_id, std::forward(args)...); + } + + for (int task_id = 0; task_id < num_threads_; ++task_id) + { + threads[task_id].join(); + } +} +} // namespace qmcplusplus + +#endif From 39ca3b1944576b8008f1643492fc6e170692d72c Mon Sep 17 00:00:00 2001 From: Peter Doak Date: Mon, 10 Jun 2019 14:02:31 -0400 Subject: [PATCH 2/5] MiniqmcOptions class plus test. --- src/Drivers/CMakeLists.txt | 2 + src/Drivers/MiniQMCOptions.cpp | 139 ++++++++++++++++++++++ src/Drivers/MiniQMCOptions.h | 95 +++++++++++++++ src/Drivers/tests/CMakeLists.txt | 24 ++++ src/Drivers/tests/test_MiniQMCOptions.cpp | 81 +++++++++++++ 5 files changed, 341 insertions(+) create mode 100644 src/Drivers/MiniQMCOptions.cpp create mode 100644 src/Drivers/MiniQMCOptions.h create mode 100644 src/Drivers/tests/CMakeLists.txt create mode 100644 src/Drivers/tests/test_MiniQMCOptions.cpp diff --git a/src/Drivers/CMakeLists.txt b/src/Drivers/CMakeLists.txt index 6dd514cf4..f8d74a550 100644 --- a/src/Drivers/CMakeLists.txt +++ b/src/Drivers/CMakeLists.txt @@ -19,6 +19,8 @@ ENDFOREACH(p ${ESTEST}) endif() +SUBDIRS(tests) + #SET(boost_test exchange_walker) #FOREACH(p ${boost_test}) # ADD_EXECUTABLE( ${p} ${p}.cpp) diff --git a/src/Drivers/MiniQMCOptions.cpp b/src/Drivers/MiniQMCOptions.cpp new file mode 100644 index 000000000..0bd3bbd15 --- /dev/null +++ b/src/Drivers/MiniQMCOptions.cpp @@ -0,0 +1,139 @@ +//////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source +// License. See LICENSE file in top directory for details. +// +// Copyright (c) 2019 QMCPACK developers. +// +// File developed by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File created by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +//////////////////////////////////////////////////////////////////////////////// + +#include "Drivers/MiniQMCOptions.h" +#include "Utilities/OutputManager.h" + +namespace qmcplusplus +{ +MiniQMCOptions readOptions(int argc, char** argv) +{ + MiniQMCOptions mq_opt; + using QMCT = QMCTraits; + int opt; + while (optind < argc) + { + if ((opt = getopt(argc, argv, "bhjvVa:c:d:g:m:n:N:r:s:t:w:x:z:")) != -1) + { + switch (opt) + { + case 'a': + mq_opt.splines_per_block = atoi(optarg); + break; + case 'b': + mq_opt.useRef = true; + break; + case 'c': // number of walkers per crowd + mq_opt.crowd_size = atoi(optarg); + break; + // case 'd': // Device choice + // mq_opt.device_number = atoi(optarg); + // break; + case 'g': // tiling1 tiling2 tiling3 + sscanf(optarg, "%d %d %d", &mq_opt.na, &mq_opt.nb, &mq_opt.nc); + break; + case 'h': + mq_opt.print_help(); + //should throw + mq_opt.valid = false; + return mq_opt; + break; + case 'j': + mq_opt.enableJ3 = true; + break; + case 'm': + { + const QMCT::RealType meshfactor = atof(optarg); + mq_opt.nx *= meshfactor; + mq_opt.ny *= meshfactor; + mq_opt.nz *= meshfactor; + } + break; + case 'n': + mq_opt.nsteps = atoi(optarg); + break; + case 'N': + mq_opt.nsubsteps = atoi(optarg); + break; + case 'r': // accept + mq_opt.accept = atof(optarg); + break; + case 's': + mq_opt.iseed = atoi(optarg); + break; + case 't': + mq_opt.timer_level_name = std::string(optarg); + break; + case 'v': + mq_opt.verbose = true; + break; + case 'V': + ::print_version(true); + return mq_opt; + //should throw + break; + case 'w': // number of crowds + mq_opt.nmovers = atoi(optarg); + break; + case 'x': // rmax + mq_opt.Rmax = atof(optarg); + break; + default: + break; + } + } + else // disallow non-option arguments + { + app_error() << "Non-option arguments not allowed = " << std::endl; + mq_opt.valid = false; + mq_opt.print_help(); + return mq_opt; + //should throw + } + } + return mq_opt; +} + +void MiniQMCOptions::print_help() +{ + app_summary() << "usage:" << '\n'; + app_summary() << " miniqmc [-bhjvV] [-g \"n0 n1 n2\"] [-m meshfactor]" << '\n'; + app_summary() << " [-n steps] [-N substeps] [-x rmax]" << '\n'; + app_summary() << " [-r AcceptanceRatio] [-s seed] [-w walkers]" << '\n'; + app_summary() << " [-a tile_size] [-t timer_level]" << '\n'; + app_summary() << "options:" << '\n'; + app_summary() << " -a splines per spline block default: num of orbs" << '\n'; + app_summary() << " -b use reference implementations default: off" << '\n'; + app_summary() << " -g set the 3D tiling. default: 1 1 1" << '\n'; + app_summary() << " -h print help and exit" << '\n'; + app_summary() << " -j enable three body Jastrow default: off" << '\n'; + app_summary() << " -m meshfactor default: 1.0" << '\n'; + app_summary() << " -n number of MC steps default: 5" << '\n'; + app_summary() << " -N number of MC substeps default: 1" << '\n'; + app_summary() << " -p crowd size default: 1\n"; + app_summary() << " -r set the acceptance ratio. default: 0.5" << '\n'; + app_summary() << " -s set the random seed. default: 11" << '\n'; + app_summary() << " -t timer level: coarse or fine default: fine" << '\n'; + app_summary() << " -w number of crowds default: 1" << '\n'; + app_summary() << " -v verbose output" << '\n'; + app_summary() << " -V print version information and exit" << '\n'; + app_summary() << " -x set the Rmax. default: 1.7" << '\n'; + //app_summary() << " -d device implementation. default: CPU " << '\n'; + //app_summary() << " Available devices:" << '\n'; + // hana::for_each(devices_range, [&](auto x) { + // std::string enum_name(hana::to(device_names[x])); + // app_summary() << " " << x << ". " << enum_name << '\n'; + // }); +} + +} // namespace qmcplusplus diff --git a/src/Drivers/MiniQMCOptions.h b/src/Drivers/MiniQMCOptions.h new file mode 100644 index 000000000..ae11ccad7 --- /dev/null +++ b/src/Drivers/MiniQMCOptions.h @@ -0,0 +1,95 @@ +//////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source +// License. See LICENSE file in top directory for details. +// +// Copyright (c) 2019 QMCPACK developers. +// +// File developed by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File created by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +//////////////////////////////////////////////////////////////////////////////// + +#ifndef QMCPLUSPLUS_MINIQMC_OPTIONS_H +#define QMCPLUSPLUS_MINIQMC_OPTIONS_H + +#include +#include +#include +#include "Utilities/qmcpack_version.h" +#include "Utilities/NewTimer.h" + +namespace qmcplusplus +{ +enum MiniQMCTimers +{ + Timer_Total, + Timer_Init, + Timer_Diffusion, + Timer_ECP, + Timer_Value, + Timer_evalGrad, + Timer_evalVGH, + Timer_ratioGrad, + Timer_Update, +}; + +/** Reads and holds the options to support more flexible non 'c' main drivers + * + */ +class MiniQMCOptions +{ +public: + TimerNameList_t MiniQMCTimerNames{ + {Timer_Total, "Total"}, + {Timer_Init, "Initialization"}, + {Timer_Diffusion, "Diffusion"}, + {Timer_ECP, "Pseudopotential"}, + {Timer_Value, "Value"}, + {Timer_evalGrad, "Current Gradient"}, + {Timer_evalVGH, "Spline Hessian Evaluation"}, + {Timer_ratioGrad, "New Gradient"}, + {Timer_Update, "Update"}, + }; + + static void print_help(); + + using QMCT = QMCTraits; + //Devices device = Devices::CPU; + bool valid = true; + //int device_number = 0; + int na = 1; + int nb = 1; + int nc = 1; + int nsteps = 5; + int iseed = 11; + int nx = 37, ny = 37, nz = 37; + int nmovers = 1; + // thread blocking + int splines_per_block = -1; + int nsubsteps = 1; + int nels = 0; + // Set cutoff for NLPP use. + // This makes precision an issue to select at run time. + QMCT::RealType Rmax = 1.7; + QMCT::RealType accept = 0.5; + //useRef is a particular implementation of numerous objects fix that and remove this option + bool useRef = false; + bool enableJ3 = false; + bool enableCrowd = false; + bool verbose = false; + std::string timer_level_name = "fine"; + TimerList_t Timers; + + int crowd_size; + + MiniQMCOptions() = default; + MiniQMCOptions(const MiniQMCOptions&) = default; // { std::cout << "MiniQMCOptions copy made" << '\n'; } +}; + +MiniQMCOptions readOptions(int argc,char** argv); + +} // namespace qmcplusplus + +#endif diff --git a/src/Drivers/tests/CMakeLists.txt b/src/Drivers/tests/CMakeLists.txt new file mode 100644 index 000000000..127ace7b1 --- /dev/null +++ b/src/Drivers/tests/CMakeLists.txt @@ -0,0 +1,24 @@ +#////////////////////////////////////////////////////////////////////////////////////// +#// This file is distributed under the University of Illinois/NCSA Open Source License. +#// See LICENSE file in top directory for details. +#// +#// Copyright (c) 2019 QMCPACK developers. +#// +#// File developed by: +#// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +#// +#// File created by: +#// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +#//////////////////////////////////////////////////////////////////////////////// + +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QMCPACK_UNIT_TEST_DIR}) + +SET(SRC_DIR Drivers) +SET(UTEST_EXE test_${SRC_DIR}) +SET(UTEST_NAME unit_test_${SRC_DIR}) + + +ADD_EXECUTABLE(${UTEST_EXE} ../../Utilities/catch-main.cpp ../MiniQMCOptions.cpp test_MiniQMCOptions.cpp) +TARGET_LINK_LIBRARIES(${UTEST_EXE} qmcutil ${MPI_LIBRARY}) + +ADD_UNIT_TEST(${UTEST_NAME} "${QMCPACK_UNIT_TEST_DIR}/${UTEST_EXE}") diff --git a/src/Drivers/tests/test_MiniQMCOptions.cpp b/src/Drivers/tests/test_MiniQMCOptions.cpp new file mode 100644 index 000000000..e8d20949d --- /dev/null +++ b/src/Drivers/tests/test_MiniQMCOptions.cpp @@ -0,0 +1,81 @@ +//////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source +// License. See LICENSE file in top directory for details. +// +// Copyright (c) 2019 QMCPACK developers. +// +// File developed by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File created by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "catch.hpp" +#include "Drivers/MiniQMCOptions.h" + +/** @file + * + * For now we omit testing help and version output + */ + +namespace qmcplusplus +{ + +TEST_CASE("MiniQMCOptions Read", "[Application]") { + int argc = 26; + std::vector opt_strs = {"dummy_progname", + "-a","256", + "-b", + "-c","8", + "-g","2 1 3", + "-j", + "-m","256", + "-n","10", + "-N","1", + "-r","0.75", + "-s","140", + "-t","fine", + "-v", + "-w","20", + "-x","1.7" + }; + + std::vector option_ptrs; + option_ptrs.reserve(argc + 1); + std::transform(begin(opt_strs), end(opt_strs), + std::back_inserter(option_ptrs), + [](std::string& s) { char * ptr = new char[s.length() + 1]; + std::strcpy(ptr, s.c_str() ); + return ptr;}); + option_ptrs.push_back(nullptr); + MiniQMCOptions mq_opt = readOptions(argc, option_ptrs.data()); + REQUIRE(mq_opt.valid); + std::for_each(begin(option_ptrs), end(option_ptrs), + [](char* c) { delete[] c; }); + REQUIRE(mq_opt.splines_per_block == 256); + REQUIRE(mq_opt.useRef); + REQUIRE(mq_opt.crowd_size == 8); + REQUIRE(mq_opt.na == 2); + REQUIRE(mq_opt.nb == 1); + REQUIRE(mq_opt.nc == 3); + REQUIRE(mq_opt.enableJ3); + REQUIRE(mq_opt.nx == 256 * 37); // PD: yes this 37 is hard coded into the options + REQUIRE(mq_opt.ny == 256 * 37); // I carried it over from miniqmc_sync_move.cpp + REQUIRE(mq_opt.nz == 256 * 37); + REQUIRE(mq_opt.nsteps == 10); + REQUIRE(mq_opt.nsubsteps == 1); + REQUIRE(mq_opt.accept == 0.75); + REQUIRE(mq_opt.iseed == 140); + REQUIRE(mq_opt.timer_level_name == "fine"); + REQUIRE(mq_opt.verbose); + REQUIRE(mq_opt.nmovers == 20); + REQUIRE(mq_opt.Rmax == 1.7); + + +} + +} + From b94511bbd9b8f97c1dea7869138871e4cf258dfc Mon Sep 17 00:00:00 2001 From: Peter Doak Date: Mon, 10 Jun 2019 16:10:08 -0400 Subject: [PATCH 3/5] test for ParalellBlock made cleaner with C++14 --- CMakeLists.txt | 2 +- src/Utilities/ParallelBlock.hpp | 46 +++++------- src/Utilities/tests/CMakeLists.txt | 2 +- src/Utilities/tests/test_ParallelBlock.cpp | 84 ++++++++++++++++++++++ 4 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 src/Utilities/tests/test_ParallelBlock.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a020de2c6..31109bb21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,7 +269,7 @@ ELSE(CMAKE_TOOLCHAIN_FILE) ENDIF() # requires C++11 standard - SET(CMAKE_CXX_STANDARD 11) + SET(CMAKE_CXX_STANDARD 14) SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_CXX_EXTENSIONS OFF) diff --git a/src/Utilities/ParallelBlock.hpp b/src/Utilities/ParallelBlock.hpp index 766919213..af5eaf250 100644 --- a/src/Utilities/ParallelBlock.hpp +++ b/src/Utilities/ParallelBlock.hpp @@ -16,19 +16,11 @@ #include #include +#include +#include namespace qmcplusplus { -template -class TaskWrapper -{ - F f; - template - void operator()(T&&... args) - { - f(std::forward(args)...); - } -}; enum class ParallelBlockThreading { @@ -60,7 +52,6 @@ class ParallelBlockBarrier template inline void ParallelBlockBarrier::wait() { - std::cout << "At omp barrier\n"; #pragma omp barrier } @@ -89,7 +80,7 @@ class ParallelBlock unsigned int num_threads_; }; -template +template template void ParallelBlock::operator()(F&& f, Args&&... args) @@ -100,20 +91,7 @@ void ParallelBlock::operator()(F&& f, Args&&... args) f(task_id, std::forward(args)...); } } - -template -template -void ParallelBlock::operator()(F&& f, ParallelBlockBarrier& barrier, Args&&... args) - -{ - omp_set_num_threads(num_threads_); -#pragma omp parallel for - for (int task_id = 0; task_id < num_threads_; ++task_id) - { - f(task_id, barrier, std::forward(args)...); - } -} - + template<> template void ParallelBlock::operator()(F&& f, Args&&... args) @@ -123,7 +101,7 @@ void ParallelBlock::operator()(F&& f, Args&&... arg for (int task_id = 0; task_id < num_threads_; ++task_id) { - threads[task_id] = std::thread(TaskWrapper{std::forward(f)}, task_id, std::forward(args)...); + threads[task_id] = std::thread(std::forward(f), task_id, std::forward(args)...); } for (int task_id = 0; task_id < num_threads_; ++task_id) @@ -131,6 +109,20 @@ void ParallelBlock::operator()(F&& f, Args&&... arg threads[task_id].join(); } } + +template +template +void ParallelBlock::operator()(F&& f, ParallelBlockBarrier& barrier, Args&&... args) + +{ + omp_set_num_threads(num_threads_); +#pragma omp parallel for + for (int task_id = 0; task_id < num_threads_; ++task_id) + { + f(task_id, barrier, std::forward(args)...); + } +} + } // namespace qmcplusplus #endif diff --git a/src/Utilities/tests/CMakeLists.txt b/src/Utilities/tests/CMakeLists.txt index c3eae55b5..d04a12e62 100644 --- a/src/Utilities/tests/CMakeLists.txt +++ b/src/Utilities/tests/CMakeLists.txt @@ -15,7 +15,7 @@ SET(SRC_DIR utilities) SET(UTEST_EXE test_${SRC_DIR}) SET(UTEST_NAME unit_test_${SRC_DIR}) -ADD_EXECUTABLE(${UTEST_EXE} ../../Utilities/catch-main.cpp test_PrimeNumberSet.cpp) +ADD_EXECUTABLE(${UTEST_EXE} ../../Utilities/catch-main.cpp test_PrimeNumberSet.cpp test_ParallelBlock.cpp) TARGET_LINK_LIBRARIES(${UTEST_EXE} qmcutil ${QMC_UTIL_LIBS} ${MPI_LIBRARY}) ADD_UNIT_TEST(${UTEST_NAME} "${QMCPACK_UNIT_TEST_DIR}/${UTEST_EXE}") diff --git a/src/Utilities/tests/test_ParallelBlock.cpp b/src/Utilities/tests/test_ParallelBlock.cpp new file mode 100644 index 000000000..ccf600e9d --- /dev/null +++ b/src/Utilities/tests/test_ParallelBlock.cpp @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source +// License. See LICENSE file in top directory for details. +// +// Copyright (c) 2019 QMCPACK developers. +// +// File developed by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File created by: +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "catch.hpp" +#include "Utilities/ParallelBlock.hpp" + +/** @file + * + * We assume omp and std threading are always available. + * Boost::HANA would simplify this... + * i.e. one test could be written for all the implementations + */ + +namespace qmcplusplus +{ + + +template +struct testTaskBarrier +{ + static void test(const int ip, + ParallelBlockBarrier& barrier, + std::atomic& counter) +{ + counter.fetch_add(1); +} +}; + +template +struct testTask +{ + static void test(const int ip, + std::atomic& counter) +{ + counter.fetch_add(1); +} +}; + + +TEST_CASE("ParallelBlock OPENMP with Block Barrier", "[Utilities]") { + int threads = 8; + constexpr ParallelBlockThreading DT = ParallelBlockThreading::OPENMP; + ParallelBlock
par_block(threads); + ParallelBlockBarrier
barrier(threads); + std::atomic counter; + counter = 0; + par_block(testTaskBarrier
::test, barrier, counter); + REQUIRE(counter == 8); +} + +TEST_CASE("ParallelBlock OPENMP", "[Utilities]") { + int threads = 8; + constexpr ParallelBlockThreading DT = ParallelBlockThreading::OPENMP; + ParallelBlock
par_block(threads); + std::atomic counter; + counter = 0; + par_block(testTask
::test, counter); + REQUIRE(counter == 8); +} + +TEST_CASE("ParallelBlock std::thread", "[Utilities]") { + int threads = 8; + constexpr ParallelBlockThreading DTS = ParallelBlockThreading::STD; + ParallelBlock par_block(threads); + std::atomic counter; + counter = 0; + par_block(testTask::test, std::ref(counter)); + REQUIRE(counter == 8); +} + +} + From cee74d97ed337b25d41e6aa68429d94975b9f141 Mon Sep 17 00:00:00 2001 From: Peter Doak Date: Tue, 11 Jun 2019 17:12:27 -0400 Subject: [PATCH 4/5] changes MiniQMCOptions for clarity and consistency --- src/Drivers/MiniQMCOptions.cpp | 12 ++++++++---- src/Drivers/MiniQMCOptions.h | 8 ++++---- src/Drivers/tests/test_MiniQMCOptions.cpp | 8 +++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Drivers/MiniQMCOptions.cpp b/src/Drivers/MiniQMCOptions.cpp index 0bd3bbd15..581dc4b4e 100644 --- a/src/Drivers/MiniQMCOptions.cpp +++ b/src/Drivers/MiniQMCOptions.cpp @@ -23,7 +23,7 @@ MiniQMCOptions readOptions(int argc, char** argv) int opt; while (optind < argc) { - if ((opt = getopt(argc, argv, "bhjvVa:c:d:g:m:n:N:r:s:t:w:x:z:")) != -1) + if ((opt = getopt(argc, argv, "bhjvVa:c:C:d:g:m:n:N:r:s:t:w:x:z:")) != -1) { switch (opt) { @@ -33,6 +33,9 @@ MiniQMCOptions readOptions(int argc, char** argv) case 'b': mq_opt.useRef = true; break; + case 'C': // number of crowds + mq_opt.num_crowds = atoi(optarg); + break; case 'c': // number of walkers per crowd mq_opt.crowd_size = atoi(optarg); break; @@ -83,7 +86,7 @@ MiniQMCOptions readOptions(int argc, char** argv) //should throw break; case 'w': // number of crowds - mq_opt.nmovers = atoi(optarg); + mq_opt.walkers_per_rank = atoi(optarg); break; case 'x': // rmax mq_opt.Rmax = atof(optarg); @@ -120,11 +123,12 @@ void MiniQMCOptions::print_help() app_summary() << " -m meshfactor default: 1.0" << '\n'; app_summary() << " -n number of MC steps default: 5" << '\n'; app_summary() << " -N number of MC substeps default: 1" << '\n'; - app_summary() << " -p crowd size default: 1\n"; + app_summary() << " -c crowd size default: 1\n"; + app_summary() << " -C number of crowds default: 1\n"; app_summary() << " -r set the acceptance ratio. default: 0.5" << '\n'; app_summary() << " -s set the random seed. default: 11" << '\n'; app_summary() << " -t timer level: coarse or fine default: fine" << '\n'; - app_summary() << " -w number of crowds default: 1" << '\n'; + app_summary() << " -w walkers per rank default: 1" << '\n'; app_summary() << " -v verbose output" << '\n'; app_summary() << " -V print version information and exit" << '\n'; app_summary() << " -x set the Rmax. default: 1.7" << '\n'; diff --git a/src/Drivers/MiniQMCOptions.h b/src/Drivers/MiniQMCOptions.h index ae11ccad7..ee8520bfa 100644 --- a/src/Drivers/MiniQMCOptions.h +++ b/src/Drivers/MiniQMCOptions.h @@ -65,7 +65,7 @@ class MiniQMCOptions int nsteps = 5; int iseed = 11; int nx = 37, ny = 37, nz = 37; - int nmovers = 1; + int num_crowds = 1; // thread blocking int splines_per_block = -1; int nsubsteps = 1; @@ -81,9 +81,9 @@ class MiniQMCOptions bool verbose = false; std::string timer_level_name = "fine"; TimerList_t Timers; - - int crowd_size; - + + int crowd_size = 1; + int walkers_per_rank = 0; MiniQMCOptions() = default; MiniQMCOptions(const MiniQMCOptions&) = default; // { std::cout << "MiniQMCOptions copy made" << '\n'; } }; diff --git a/src/Drivers/tests/test_MiniQMCOptions.cpp b/src/Drivers/tests/test_MiniQMCOptions.cpp index e8d20949d..8cf519ee5 100644 --- a/src/Drivers/tests/test_MiniQMCOptions.cpp +++ b/src/Drivers/tests/test_MiniQMCOptions.cpp @@ -25,7 +25,7 @@ namespace qmcplusplus { TEST_CASE("MiniQMCOptions Read", "[Application]") { - int argc = 26; + int argc = 28; std::vector opt_strs = {"dummy_progname", "-a","256", "-b", @@ -39,7 +39,8 @@ TEST_CASE("MiniQMCOptions Read", "[Application]") { "-s","140", "-t","fine", "-v", - "-w","20", + "-w","200", + "-C","10", "-x","1.7" }; @@ -58,6 +59,7 @@ TEST_CASE("MiniQMCOptions Read", "[Application]") { REQUIRE(mq_opt.splines_per_block == 256); REQUIRE(mq_opt.useRef); REQUIRE(mq_opt.crowd_size == 8); + REQUIRE(mq_opt.num_crowds == 10); REQUIRE(mq_opt.na == 2); REQUIRE(mq_opt.nb == 1); REQUIRE(mq_opt.nc == 3); @@ -71,7 +73,7 @@ TEST_CASE("MiniQMCOptions Read", "[Application]") { REQUIRE(mq_opt.iseed == 140); REQUIRE(mq_opt.timer_level_name == "fine"); REQUIRE(mq_opt.verbose); - REQUIRE(mq_opt.nmovers == 20); + REQUIRE(mq_opt.walkers_per_rank == 200); REQUIRE(mq_opt.Rmax == 1.7); From a354a6ac83876d7145e672720ad370d3f2278e19 Mon Sep 17 00:00:00 2001 From: Peter Doak Date: Tue, 11 Jun 2019 17:42:32 -0400 Subject: [PATCH 5/5] downgraded to c++11 again, better vars less // --- CMakeLists.txt | 2 +- src/Drivers/MiniQMCOptions.cpp | 14 ++++++-------- src/Drivers/MiniQMCOptions.h | 11 +++++------ src/Drivers/tests/test_MiniQMCOptions.cpp | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31109bb21..a020de2c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,7 +269,7 @@ ELSE(CMAKE_TOOLCHAIN_FILE) ENDIF() # requires C++11 standard - SET(CMAKE_CXX_STANDARD 14) + SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_CXX_EXTENSIONS OFF) diff --git a/src/Drivers/MiniQMCOptions.cpp b/src/Drivers/MiniQMCOptions.cpp index 581dc4b4e..deae44612 100644 --- a/src/Drivers/MiniQMCOptions.cpp +++ b/src/Drivers/MiniQMCOptions.cpp @@ -33,10 +33,10 @@ MiniQMCOptions readOptions(int argc, char** argv) case 'b': mq_opt.useRef = true; break; - case 'C': // number of crowds + case 'C': mq_opt.num_crowds = atoi(optarg); break; - case 'c': // number of walkers per crowd + case 'c': mq_opt.crowd_size = atoi(optarg); break; // case 'd': // Device choice @@ -68,8 +68,8 @@ MiniQMCOptions readOptions(int argc, char** argv) case 'N': mq_opt.nsubsteps = atoi(optarg); break; - case 'r': // accept - mq_opt.accept = atof(optarg); + case 'r': + mq_opt.accept_ratio = atof(optarg); break; case 's': mq_opt.iseed = atoi(optarg); @@ -83,12 +83,11 @@ MiniQMCOptions readOptions(int argc, char** argv) case 'V': ::print_version(true); return mq_opt; - //should throw break; - case 'w': // number of crowds + case 'w': mq_opt.walkers_per_rank = atoi(optarg); break; - case 'x': // rmax + case 'x': mq_opt.Rmax = atof(optarg); break; default: @@ -101,7 +100,6 @@ MiniQMCOptions readOptions(int argc, char** argv) mq_opt.valid = false; mq_opt.print_help(); return mq_opt; - //should throw } } return mq_opt; diff --git a/src/Drivers/MiniQMCOptions.h b/src/Drivers/MiniQMCOptions.h index ee8520bfa..056a71a0f 100644 --- a/src/Drivers/MiniQMCOptions.h +++ b/src/Drivers/MiniQMCOptions.h @@ -35,7 +35,7 @@ enum MiniQMCTimers Timer_Update, }; -/** Reads and holds the options to support more flexible non 'c' main drivers +/** Reads and holds the options to support more flexible non 'c main()' drivers * */ class MiniQMCOptions @@ -66,26 +66,25 @@ class MiniQMCOptions int iseed = 11; int nx = 37, ny = 37, nz = 37; int num_crowds = 1; - // thread blocking int splines_per_block = -1; int nsubsteps = 1; int nels = 0; // Set cutoff for NLPP use. // This makes precision an issue to select at run time. QMCT::RealType Rmax = 1.7; - QMCT::RealType accept = 0.5; - //useRef is a particular implementation of numerous objects fix that and remove this option + QMCT::RealType accept_ratio = 0.5; + //useRef is a particular implementation of numerous objects fix that remove this option + //and many branch statements bool useRef = false; bool enableJ3 = false; bool enableCrowd = false; bool verbose = false; std::string timer_level_name = "fine"; TimerList_t Timers; - int crowd_size = 1; int walkers_per_rank = 0; MiniQMCOptions() = default; - MiniQMCOptions(const MiniQMCOptions&) = default; // { std::cout << "MiniQMCOptions copy made" << '\n'; } + MiniQMCOptions(const MiniQMCOptions&) = default; }; MiniQMCOptions readOptions(int argc,char** argv); diff --git a/src/Drivers/tests/test_MiniQMCOptions.cpp b/src/Drivers/tests/test_MiniQMCOptions.cpp index 8cf519ee5..d5f4d554d 100644 --- a/src/Drivers/tests/test_MiniQMCOptions.cpp +++ b/src/Drivers/tests/test_MiniQMCOptions.cpp @@ -69,7 +69,7 @@ TEST_CASE("MiniQMCOptions Read", "[Application]") { REQUIRE(mq_opt.nz == 256 * 37); REQUIRE(mq_opt.nsteps == 10); REQUIRE(mq_opt.nsubsteps == 1); - REQUIRE(mq_opt.accept == 0.75); + REQUIRE(mq_opt.accept_ratio == 0.75); REQUIRE(mq_opt.iseed == 140); REQUIRE(mq_opt.timer_level_name == "fine"); REQUIRE(mq_opt.verbose);