From 2808a78822711bb28f2402ba4e2376d6ce65db90 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 2 Aug 2023 17:28:34 -0400 Subject: [PATCH] more updates to preferences dialog and supporting code. almost done. --- tools/lammps-gui/lammpsgui.cpp | 60 ++++++++-- tools/lammps-gui/lammpsgui.h | 1 - tools/lammps-gui/lammpswrapper.cpp | 18 +++ tools/lammps-gui/lammpswrapper.h | 2 + tools/lammps-gui/preferences.cpp | 173 +++++++++++++++++++++++++---- tools/lammps-gui/preferences.h | 14 ++- 6 files changed, 238 insertions(+), 30 deletions(-) diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 066d7ca373..0d483ac2d4 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -81,9 +81,11 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) : // restorge and initialize settings QSettings settings; + // check and initialize nthreads setting. Default is to use max, + // but not override OMP_NUM_THREADS and preferences setting. #if defined(_OPENMP) // use maximum number of available threads unless OMP_NUM_THREADS was set - nthreads = settings.value("nthreads", omp_get_max_threads()).toInt(); + int nthreads = settings.value("nthreads", omp_get_max_threads()).toInt(); #if _WIN32 if (!getenv("OMP_NUM_THREADS")) { _putenv_s("OMP_NUM_THREADS", std::to_string(nthreads).c_str()); @@ -92,8 +94,9 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) : setenv("OMP_NUM_THREADS", std::to_string(nthreads).c_str(), 0); #endif #else - nthreads = settings.value("nthreads", 1).toInt(); + int nthreads = settings.value("nthreads", 1).toInt(); #endif + settings.setValue("nthreads", QString::number(nthreads)); const char *tmpdir = getenv("TMPDIR"); if (!tmpdir) tmpdir = getenv("TMP"); @@ -110,8 +113,6 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) : lammps_args.push_back(mystrdup("LAMMPS-GUI")); lammps_args.push_back(mystrdup("-log")); lammps_args.push_back(mystrdup("none")); - // lammps_args.push_back(mystrdup("-suffix")); - // lammps_args.push_back(mystrdup("omp")); setWindowIcon(QIcon(":/lammps-icon-128x128.png")); #if (__APPLE__) @@ -431,9 +432,11 @@ void LammpsGui::run_done() void LammpsGui::run_buffer() { + QSettings settings; progress->setValue(0); dirstatus->hide(); progress->show(); + int nthreads = settings.value("nthreads", 1).toInt(); status->setText(QString("Running LAMMPS with %1 thread(s)...").arg(nthreads)); status->repaint(); start_lammps(); @@ -620,18 +623,61 @@ void LammpsGui::preferences() { Preferences prefs(&lammps); if (prefs.exec() == QDialog::Accepted) { - - // extract and apply settings as needed + // must delete LAMMPS instance after setting may be changed so we can apply different + // suffixes + lammps.close(); } } void LammpsGui::start_lammps() { + // temporary extend lammps_args with additional arguments + int initial_narg = lammps_args.size(); + QSettings settings; + int nthreads = settings.value("nthreads", 1).toInt(); + int accel = settings.value("accelerator", AcceleratorTab::None).toInt(); + if (accel == AcceleratorTab::Opt) { + lammps_args.push_back(mystrdup("-suffix")); + lammps_args.push_back(mystrdup("opt")); + } else if (accel == AcceleratorTab::OpenMP) { + lammps_args.push_back(mystrdup("-suffix")); + lammps_args.push_back(mystrdup("omp")); + lammps_args.push_back(mystrdup("-pk")); + lammps_args.push_back(mystrdup("omp")); + lammps_args.push_back(mystrdup(std::to_string(nthreads))); + } else if (accel == AcceleratorTab::Intel) { + lammps_args.push_back(mystrdup("-suffix")); + lammps_args.push_back(mystrdup("intel")); + lammps_args.push_back(mystrdup("-pk")); + lammps_args.push_back(mystrdup("intel")); + lammps_args.push_back(mystrdup(std::to_string(nthreads))); + } else if (accel == AcceleratorTab::Gpu) { + lammps_args.push_back(mystrdup("-suffix")); + lammps_args.push_back(mystrdup("gpu")); + lammps_args.push_back(mystrdup("-pk")); + lammps_args.push_back(mystrdup("gpu")); + lammps_args.push_back(mystrdup("0")); + } + + if (settings.value("echo", "0").toInt()) { + lammps_args.push_back(mystrdup("-echo")); + lammps_args.push_back(mystrdup("screen")); + } + if (settings.value("cite", "0").toInt()) { + lammps_args.push_back(mystrdup("-cite")); + lammps_args.push_back(mystrdup("screen")); + } + char **args = lammps_args.data(); int narg = lammps_args.size(); - lammps.open(narg, args); + // delete additional arguments again (3 were there initially + while (lammps_args.size() > initial_narg) { + delete lammps_args.back(); + lammps_args.pop_back(); + } + if (lammps.has_error()) { constexpr int BUFLEN = 1024; char errorbuf[BUFLEN]; diff --git a/tools/lammps-gui/lammpsgui.h b/tools/lammps-gui/lammpsgui.h index 01ab3d0c33..372d327448 100644 --- a/tools/lammps-gui/lammpsgui.h +++ b/tools/lammps-gui/lammpsgui.h @@ -94,7 +94,6 @@ private: LammpsWrapper lammps; std::string plugin_path; bool is_running; - int nthreads; QList recent_files; std::vector lammps_args; }; diff --git a/tools/lammps-gui/lammpswrapper.cpp b/tools/lammps-gui/lammpswrapper.cpp index 361a69c784..d8a8b78568 100644 --- a/tools/lammps-gui/lammpswrapper.cpp +++ b/tools/lammps-gui/lammpswrapper.cpp @@ -151,6 +151,24 @@ void LammpsWrapper::finalize() #endif } +bool LammpsWrapper::config_has_package(const char *package) const +{ +#if defined(LAMMPS_GUI_USE_PLUGIN) + return ((liblammpsplugin_t *)plugin_handle)->config_has_package(package) != 0; +#else + return lammps_config_has_package(package) != 0; +#endif +} + +bool LammpsWrapper::has_gpu_device() const +{ +#if defined(LAMMPS_GUI_USE_PLUGIN) + return ((liblammpsplugin_t *)plugin_handle)->has_gpu_device() != 0; +#else + return lammps_has_gpu_device() != 0; +#endif +} + #if defined(LAMMPS_GUI_USE_PLUGIN) bool LammpsWrapper::has_plugin() const { diff --git a/tools/lammps-gui/lammpswrapper.h b/tools/lammps-gui/lammpswrapper.h index 858cc12e34..5f33c1f6b6 100644 --- a/tools/lammps-gui/lammpswrapper.h +++ b/tools/lammps-gui/lammpswrapper.h @@ -34,6 +34,8 @@ public: bool is_running(); bool has_error() const; int get_last_error_message(char *errorbuf, int buflen); + bool config_has_package(const char *pkg) const; + bool has_gpu_device() const; bool load_lib(const char *lammpslib); bool has_plugin() const; diff --git a/tools/lammps-gui/preferences.cpp b/tools/lammps-gui/preferences.cpp index 7b14b01718..2784c57a80 100644 --- a/tools/lammps-gui/preferences.cpp +++ b/tools/lammps-gui/preferences.cpp @@ -13,9 +13,11 @@ #include "preferences.h" +#include #include #include #include +#include #include #include #include @@ -26,11 +28,16 @@ #include "lammpswrapper.h" +#if defined(_OPENMP) +#include +#endif + Preferences::Preferences(LammpsWrapper *_lammps, QWidget *parent) : QDialog(parent), tabWidget(new QTabWidget), buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)), settings(new QSettings), lammps(_lammps) { + tabWidget->addTab(new GeneralTab(settings), "General Settings"); tabWidget->addTab(new AcceleratorTab(settings, lammps), "Accelerators"); tabWidget->addTab(new SnapshotTab(settings), "Snapshot Image"); @@ -42,7 +49,7 @@ Preferences::Preferences(LammpsWrapper *_lammps, QWidget *parent) : layout->addWidget(buttonBox); setLayout(layout); setWindowTitle("LAMMPS-GUI - Preferences"); - resize(400, 320); + resize(500, 400); } Preferences::~Preferences() @@ -56,46 +63,172 @@ void Preferences::accept() { // store all data in settings class // and then confirm accepting + + // store selected accelerator + QList allButtons = tabWidget->findChildren(); + for (int i = 0; i < allButtons.size(); ++i) { + if (allButtons[i]->isChecked()) { + if (allButtons[i]->objectName() == "none") + settings->setValue("accelerator", QString::number(AcceleratorTab::None)); + if (allButtons[i]->objectName() == "opt") + settings->setValue("accelerator", QString::number(AcceleratorTab::Opt)); + if (allButtons[i]->objectName() == "openmp") + settings->setValue("accelerator", QString::number(AcceleratorTab::OpenMP)); + if (allButtons[i]->objectName() == "intel") + settings->setValue("accelerator", QString::number(AcceleratorTab::Intel)); + if (allButtons[i]->objectName() == "kokkos") + settings->setValue("accelerator", QString::number(AcceleratorTab::Kokkos)); + if (allButtons[i]->objectName() == "gpu") + settings->setValue("accelerator", QString::number(AcceleratorTab::Gpu)); + } + } + + // store number of threads + QLineEdit *field = tabWidget->findChild("nthreads"); + if (field) + if (field->hasAcceptableInput()) settings->setValue("nthreads", field->text()); + + // store image width, height, and zoom + + settings->beginGroup("snapshot"); + field = tabWidget->findChild("xsize"); + if (field) + if (field->hasAcceptableInput()) settings->setValue("xsize", field->text()); + field = tabWidget->findChild("ysize"); + if (field) + if (field->hasAcceptableInput()) settings->setValue("ysize", field->text()); + field = tabWidget->findChild("zoom"); + if (field) + if (field->hasAcceptableInput()) settings->setValue("zoom", field->text()); + settings->endGroup(); + + // general settings + QCheckBox *box = tabWidget->findChild("echo"); + if (box) settings->setValue("echo", box->isChecked() ? "1" : "0"); + box = tabWidget->findChild("cite"); + if (box) settings->setValue("cite", box->isChecked() ? "1" : "0"); + QDialog::accept(); } +GeneralTab::GeneralTab(QSettings *_settings, QWidget *parent) : QWidget(parent), settings(_settings) +{ + auto *layout = new QVBoxLayout; + + auto *echo = new QCheckBox("Echo input to log"); + echo->setCheckState(settings->value("echo", "0").toInt() ? Qt::Checked : Qt::Unchecked); + echo->setObjectName("echo"); + auto *cite = new QCheckBox("Include Citations"); + cite->setCheckState(settings->value("cite", "0").toInt() ? Qt::Checked : Qt::Unchecked); + cite->setObjectName("cite"); + + layout->addWidget(echo); + layout->addWidget(cite); + layout->addStretch(1); + setLayout(layout); +} + AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWidget *parent) : QWidget(parent), settings(_settings), lammps(_lammps) { - QGroupBox *accelerator = new QGroupBox("Choose Accelerator"); - QRadioButton *none = new QRadioButton("&None"); - QRadioButton *kokkos = new QRadioButton("&Kokkos"); - QRadioButton *intel = new QRadioButton("&Intel"); - QRadioButton *openmp = new QRadioButton("&OpenMP"); - QRadioButton *opt = new QRadioButton("O&pt"); + auto *mainLayout = new QHBoxLayout; + auto *accelerator = new QGroupBox("Choose Accelerator:"); + auto *none = new QRadioButton("&None"); + auto *opt = new QRadioButton("O&pt"); + auto *openmp = new QRadioButton("&OpenMP"); + auto *intel = new QRadioButton("&Intel"); + auto *kokkos = new QRadioButton("&Kokkos"); + auto *gpu = new QRadioButton("&GPU"); - none->setChecked(true); - QVBoxLayout *layout = new QVBoxLayout; - layout->addWidget(none); - layout->addWidget(kokkos); - layout->addWidget(intel); - layout->addWidget(openmp); - layout->addWidget(opt); - layout->addStretch(1); - setLayout(layout); + auto *buttonLayout = new QVBoxLayout; + buttonLayout->addWidget(none); + buttonLayout->addWidget(opt); + buttonLayout->addWidget(openmp); + buttonLayout->addWidget(intel); + buttonLayout->addWidget(kokkos); + buttonLayout->addWidget(gpu); + buttonLayout->addStretch(1); + accelerator->setLayout(buttonLayout); + mainLayout->addWidget(accelerator); + + none->setEnabled(true); + none->setObjectName("none"); + opt->setEnabled(lammps->config_has_package("OPT")); + opt->setObjectName("opt"); + openmp->setEnabled(lammps->config_has_package("OPENMP")); + openmp->setObjectName("openmp"); + intel->setEnabled(lammps->config_has_package("INTEL")); + intel->setObjectName("intel"); + kokkos->setEnabled(lammps->config_has_package("KOKKOS")); + kokkos->setObjectName("kokkos"); + gpu->setEnabled(lammps->config_has_package("GPU") && lammps->has_gpu_device()); + gpu->setObjectName("gpu"); + + int choice = settings->value("accelerator", AcceleratorTab::None).toInt(); + switch (choice) { + case AcceleratorTab::Opt: + if (opt->isEnabled()) opt->setChecked(true); + break; + case AcceleratorTab::OpenMP: + if (openmp->isEnabled()) openmp->setChecked(true); + break; + case AcceleratorTab::Intel: + if (intel->isEnabled()) intel->setChecked(true); + break; + case AcceleratorTab::Kokkos: + if (kokkos->isEnabled()) kokkos->setChecked(true); + break; + case AcceleratorTab::Gpu: + if (gpu->isEnabled()) gpu->setChecked(true); + break; + case AcceleratorTab::None: // fallthrough + default: + none->setChecked(true); + break; + } + + int maxthreads = 1; +#if defined(_OPENMP) + maxthreads = omp_get_max_threads(); +#endif + auto *choices = new QFrame; + auto *choiceLayout = new QVBoxLayout; + auto *ntlabel = new QLabel("Number of threads:"); + auto *ntchoice = new QLineEdit(settings->value("nthreads", maxthreads).toString()); + auto *intval = new QIntValidator(1, maxthreads, this); + ntchoice->setValidator(intval); + ntchoice->setObjectName("nthreads"); + + choiceLayout->addWidget(ntlabel); + choiceLayout->addWidget(ntchoice); + choices->setLayout(choiceLayout); + choiceLayout->addStretch(1); + + mainLayout->addWidget(choices); + setLayout(mainLayout); } SnapshotTab::SnapshotTab(QSettings *_settings, QWidget *parent) : QWidget(parent), settings(_settings) { - QGridLayout *grid = new QGridLayout; + auto *grid = new QGridLayout; auto *xsize = new QLabel("Image width:"); auto *ysize = new QLabel("Image height:"); auto *zoom = new QLabel("Zoom factor:"); - auto *xval = new QLineEdit(settings->value("xsize", "800").toString()); - auto *yval = new QLineEdit(settings->value("ysize", "600").toString()); - auto *zval = new QLineEdit(settings->value("zoom", "1.0").toString()); + settings->beginGroup("snapshot"); + auto *xval = new QLineEdit(settings->value("xsize", "800").toString()); + auto *yval = new QLineEdit(settings->value("ysize", "600").toString()); + auto *zval = new QLineEdit(settings->value("zoom", "1.0").toString()); + settings->endGroup(); auto *intval = new QIntValidator(100, 100000, this); xval->setValidator(intval); + xval->setObjectName("xsize"); yval->setValidator(intval); + yval->setObjectName("ysize"); zval->setValidator(new QDoubleValidator(0.01, 100.0, 100, this)); + zval->setObjectName("zoom"); grid->addWidget(xsize, 0, 0); grid->addWidget(ysize, 1, 0); diff --git a/tools/lammps-gui/preferences.h b/tools/lammps-gui/preferences.h index 1cefb79d43..f3c6b5f8a4 100644 --- a/tools/lammps-gui/preferences.h +++ b/tools/lammps-gui/preferences.h @@ -30,7 +30,7 @@ public: protected slots: void accept() override; - + private: QTabWidget *tabWidget; QDialogButtonBox *buttonBox; @@ -40,12 +40,22 @@ private: // individual tabs +class GeneralTab : public QWidget { + Q_OBJECT + +public: + explicit GeneralTab(QSettings *settings, QWidget *parent = nullptr); + +private: + QSettings *settings; +}; + class AcceleratorTab : public QWidget { Q_OBJECT public: explicit AcceleratorTab(QSettings *settings, LammpsWrapper *lammps, QWidget *parent = nullptr); - enum { None, Intel, Kokkos, OpenMP, Opt }; + enum { None, Opt, OpenMP, Intel, Kokkos, Gpu }; private: QSettings *settings;