From 38d4c581150f807ae1381072b03cb281a159b2e6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 5 Jul 2025 18:42:45 -0400 Subject: [PATCH] support setting intel precision and gpu neigh and pair/only from preferences --- tools/lammps-gui/lammpsgui.cpp | 61 +++++++++++++-- tools/lammps-gui/preferences.cpp | 127 ++++++++++++++++++++++++++----- tools/lammps-gui/preferences.h | 3 +- 3 files changed, 162 insertions(+), 29 deletions(-) diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 1d23b773b4..2e21dc1782 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -153,6 +153,17 @@ LammpsGui::LammpsGui(QWidget *parent, const QString &filename) : } settings.setValue("accelerator", accel); + // Check and initialize some settings for individual accelerator packages and commit + // GPU neighbor list on GPU versus host + bool gpuneigh = settings.value("gpuneigh", true).toBool(); + settings.setValue("gpuneigh", gpuneigh); + // accelerate only pair style (i.e. run PPPM completely on host) + bool gpupaironly = settings.value("gpupaironly", false).toBool(); + settings.setValue("gpupaironly", gpupaironly); + // INTEL package precision + int intelprec = settings.value("intelprec", QString::number(AcceleratorTab::Mixed)).toInt(); + settings.setValue("intelprec", QString::number(intelprec)); + // Check and initialize nthreads setting for when OpenMP support is compiled in. // Default is to use OMP_NUM_THREADS setting, if that is not available, then // half of max (assuming hyperthreading is enabled) and no more than 16. @@ -1911,10 +1922,13 @@ void LammpsGui::preferences() { // default settings are committed to QSettings during initialization of LAMMPS-GUI QSettings settings; - int oldthreads = settings.value("nthreads", 1).toInt(); - int oldaccel = settings.value("accelerator", AcceleratorTab::None).toInt(); - bool oldecho = settings.value("echo", false).toBool(); - bool oldcite = settings.value("cite", false).toBool(); + int oldthreads = settings.value("nthreads", 1).toInt(); + int oldaccel = settings.value("accelerator", AcceleratorTab::None).toInt(); + bool oldecho = settings.value("echo", false).toBool(); + bool oldcite = settings.value("cite", false).toBool(); + int oldiprec = settings.value("intelprec", AcceleratorTab::Mixed).toInt(); + bool oldgpuneigh = settings.value("gpuneigh", true).toBool(); + bool oldgpupair = settings.value("gpupaironly", false).toBool(); Preferences prefs(&lammps); prefs.setFont(font()); @@ -1925,9 +1939,12 @@ void LammpsGui::preferences() // suffixes or package commands int newthreads = settings.value("nthreads", nthreads).toInt(); int newaccel = settings.value("accelerator", AcceleratorTab::None).toInt(); - if ((oldaccel != newaccel) || (oldthreads != newthreads) || + int newiprec = settings.value("intelprec", AcceleratorTab::Mixed).toInt(); + if ((oldaccel != newaccel) || (oldthreads != newthreads) || (oldiprec != newiprec) || (oldecho != settings.value("echo", false).toBool()) || - (oldcite != settings.value("cite", false).toBool())) { + (oldcite != settings.value("cite", false).toBool()) || + (oldgpuneigh != settings.value("gpuneigh", true).toBool()) || + (oldgpupair != settings.value("gpupaironly", false).toBool())) { if (lammps.is_running()) { stop_run(); runner->wait(); @@ -1985,24 +2002,54 @@ void LammpsGui::start_lammps() lammps_args.push_back(mystrdup("hybrid")); lammps_args.push_back(mystrdup("intel")); 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 { lammps_args.push_back(mystrdup("intel")); } lammps_args.push_back(mystrdup("-pk")); lammps_args.push_back(mystrdup("intel")); + lammps_args.push_back(mystrdup("0")); + lammps_args.push_back(mystrdup("omp")); lammps_args.push_back(mystrdup(std::to_string(nthreads))); + lammps_args.push_back(mystrdup("mode")); + int iprec = settings.value("intelprec", AcceleratorTab::Mixed).toInt(); + if (iprec == AcceleratorTab::Double) + lammps_args.push_back(mystrdup("double")); + else if (iprec == AcceleratorTab::Mixed) + lammps_args.push_back(mystrdup("mixed")); + else if (iprec == AcceleratorTab::Single) + lammps_args.push_back(mystrdup("single")); + else // use mixed precision for invalid value so there is no syntax error crash + lammps_args.push_back(mystrdup("mixed")); } else if (accel == AcceleratorTab::Gpu) { lammps_args.push_back(mystrdup("-suffix")); if ((nthreads > 1) && lammps.config_has_package("OPENMP")) { lammps_args.push_back(mystrdup("hybrid")); lammps_args.push_back(mystrdup("gpu")); 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 { lammps_args.push_back(mystrdup("gpu")); } lammps_args.push_back(mystrdup("-pk")); lammps_args.push_back(mystrdup("gpu")); - lammps_args.push_back(mystrdup("0")); + lammps_args.push_back(mystrdup("1")); // can use only one GPU without MPI + lammps_args.push_back(mystrdup("omp")); + lammps_args.push_back(mystrdup(std::to_string(nthreads))); + lammps_args.push_back(mystrdup("neigh")); + if (settings.value("gpuneigh", true).toBool()) + lammps_args.push_back(mystrdup("yes")); + else + lammps_args.push_back(mystrdup("no")); + lammps_args.push_back(mystrdup("pair/only")); + if (settings.value("gpupaironly", false).toBool()) + lammps_args.push_back(mystrdup("on")); + else + lammps_args.push_back(mystrdup("off")); } else if (accel == AcceleratorTab::Kokkos) { lammps_args.push_back(mystrdup("-kokkos")); lammps_args.push_back(mystrdup("on")); diff --git a/tools/lammps-gui/preferences.cpp b/tools/lammps-gui/preferences.cpp index 076bd5c788..3d255f4b8b 100644 --- a/tools/lammps-gui/preferences.cpp +++ b/tools/lammps-gui/preferences.cpp @@ -99,17 +99,23 @@ void Preferences::accept() if (allButton->isChecked()) { const auto &button = allButton->objectName(); if (button == "none") - settings->setValue("accelerator", QString::number(AcceleratorTab::None)); + settings->setValue("accelerator", AcceleratorTab::None); else if (button == "opt") - settings->setValue("accelerator", QString::number(AcceleratorTab::Opt)); + settings->setValue("accelerator", AcceleratorTab::Opt); else if (button == "openmp") - settings->setValue("accelerator", QString::number(AcceleratorTab::OpenMP)); + settings->setValue("accelerator", AcceleratorTab::OpenMP); else if (button == "intel") - settings->setValue("accelerator", QString::number(AcceleratorTab::Intel)); + settings->setValue("accelerator", AcceleratorTab::Intel); else if (button == "kokkos") - settings->setValue("accelerator", QString::number(AcceleratorTab::Kokkos)); + settings->setValue("accelerator", AcceleratorTab::Kokkos); else if (button == "gpu") - settings->setValue("accelerator", QString::number(AcceleratorTab::Gpu)); + settings->setValue("accelerator", AcceleratorTab::Gpu); + else if (button == "inteldouble") + settings->setValue("intelprec", AcceleratorTab::Double); + else if (button == "intelmixed") + settings->setValue("intelprec", AcceleratorTab::Mixed); + else if (button == "intelsingle") + settings->setValue("intelprec", AcceleratorTab::Single); } } @@ -128,6 +134,12 @@ void Preferences::accept() } #endif + // store setting for GPU package + auto *box = tabWidget->findChild("gpuneigh"); + if (box) settings->setValue("gpuneigh", box->isChecked()); + box = tabWidget->findChild("gpupaironly"); + if (box) settings->setValue("gpupaironly", box->isChecked()); + // store image width, height, zoom, and rendering settings settings->beginGroup("snapshot"); @@ -140,7 +152,7 @@ void Preferences::accept() field = tabWidget->findChild("zoom"); if (field) if (field->hasAcceptableInput()) settings->setValue("zoom", field->text()); - auto *box = tabWidget->findChild("anti"); + box = tabWidget->findChild("anti"); if (box) settings->setValue("antialias", box->isChecked()); box = tabWidget->findChild("ssao"); if (box) settings->setValue("ssao", box->isChecked()); @@ -411,7 +423,10 @@ AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWi auto *kokkos = new QRadioButton("&Kokkos"); auto *gpu = new QRadioButton("GP&U"); + auto *accelframe = new QFrame; + auto *accelLayout = new QVBoxLayout; auto *buttonLayout = new QVBoxLayout; + accelLayout->addWidget(accelerator); buttonLayout->addWidget(none); buttonLayout->addWidget(opt); buttonLayout->addWidget(openmp); @@ -420,7 +435,8 @@ AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWi buttonLayout->addWidget(gpu); buttonLayout->addStretch(1); accelerator->setLayout(buttonLayout); - mainLayout->addWidget(accelerator); + accelframe->setLayout(accelLayout); + mainLayout->addWidget(accelframe); none->setEnabled(true); none->setObjectName("none"); @@ -463,24 +479,69 @@ AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWi #endif ntchoice->setObjectName("nthreads"); - connect(none, &QRadioButton::released, this, &AcceleratorTab::update_threads); - connect(opt, &QRadioButton::released, this, &AcceleratorTab::update_threads); - connect(openmp, &QRadioButton::released, this, &AcceleratorTab::update_threads); - connect(intel, &QRadioButton::released, this, &AcceleratorTab::update_threads); - connect(kokkos, &QRadioButton::released, this, &AcceleratorTab::update_threads); - connect(gpu, &QRadioButton::released, this, &AcceleratorTab::update_threads); + connect(none, &QRadioButton::released, this, &AcceleratorTab::update_accel); + connect(opt, &QRadioButton::released, this, &AcceleratorTab::update_accel); + connect(openmp, &QRadioButton::released, this, &AcceleratorTab::update_accel); + connect(intel, &QRadioButton::released, this, &AcceleratorTab::update_accel); + connect(kokkos, &QRadioButton::released, this, &AcceleratorTab::update_accel); + connect(gpu, &QRadioButton::released, this, &AcceleratorTab::update_accel); + auto *intelLayout = new QHBoxLayout; + auto *intelprec = new QGroupBox("Intel Precision:"); + auto *inteldouble = new QRadioButton("&Double"); + auto *intelmixed = new QRadioButton("&Mixed"); + auto *intelsingle = new QRadioButton("&Single"); + intelLayout->addWidget(inteldouble); + inteldouble->setObjectName("inteldouble"); + intelLayout->addWidget(intelmixed); + intelmixed->setObjectName("intelmixed"); + intelLayout->addWidget(intelsingle); + intelsingle->setObjectName("intelsingle"); + intelprec->setLayout(intelLayout); + intelprec->setObjectName("intelprec"); + intelprec->setEnabled(false); + + connect(inteldouble, &QRadioButton::released, this, &AcceleratorTab::update_accel); + connect(intelmixed, &QRadioButton::released, this, &AcceleratorTab::update_accel); + connect(intelsingle, &QRadioButton::released, this, &AcceleratorTab::update_accel); + + auto *gpuLayout = new QHBoxLayout; + auto *gpuchoice = new QGroupBox("GPU Settings:"); + auto *gpuneigh = new QCheckBox("Neighbor&list on GPU"); + auto *gpupaironly = new QCheckBox("Pair st&yles only"); + gpuLayout->addWidget(gpuneigh); + gpuneigh->setObjectName("gpuneigh"); + gpuneigh->setCheckState(settings->value("gpuneigh", true).toBool() ? Qt::Checked + : Qt::Unchecked); + gpuLayout->addWidget(gpupaironly); + gpupaironly->setObjectName("gpupaironly"); + gpupaironly->setCheckState(settings->value("gpupaironly", false).toBool() ? Qt::Checked + : Qt::Unchecked); + gpuchoice->setLayout(gpuLayout); + gpuchoice->setObjectName("gpuchoice"); + gpuchoice->setEnabled(false); + + choiceLayout->addWidget(new QLabel("Settings for accelerator packages:\n")); choiceLayout->addWidget(ntlabel); choiceLayout->addWidget(ntchoice); - choices->setLayout(choiceLayout); + choiceLayout->addWidget(intelprec); + choiceLayout->addWidget(gpuchoice); choiceLayout->addStretch(1); - + choices->setLayout(choiceLayout); mainLayout->addWidget(choices); setLayout(mainLayout); // trigger update of nthreads line editor field depending on accelerator choice // fall back on None, if configured accelerator package is no longer available int choice = settings->value("accelerator", AcceleratorTab::None).toInt(); + int iprec = settings->value("intelprec", AcceleratorTab::Mixed).toInt(); + if (iprec == AcceleratorTab::Double) + inteldouble->setChecked(true); + else if (iprec == AcceleratorTab::Mixed) + intelmixed->setChecked(true); + else if (iprec == AcceleratorTab::Single) + intelsingle->setChecked(true); + switch (choice) { case AcceleratorTab::Opt: if (opt->isEnabled()) @@ -495,10 +556,12 @@ AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWi none->click(); break; case AcceleratorTab::Intel: - if (intel->isEnabled()) + if (intel->isEnabled()) { intel->click(); - else + intelprec->setEnabled(true); + } else { none->click(); + } break; case AcceleratorTab::Kokkos: if (kokkos->isEnabled()) @@ -507,9 +570,10 @@ AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWi none->click(); break; case AcceleratorTab::Gpu: - if (gpu->isEnabled()) + if (gpu->isEnabled()) { gpu->click(); - else + gpuchoice->setEnabled(true); + } else none->click(); break; case AcceleratorTab::None: // fallthrough @@ -519,10 +583,11 @@ AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWi } } -void AcceleratorTab::update_threads() +void AcceleratorTab::update_accel() { // store selected accelerator int choice = AcceleratorTab::None; + int prec = AcceleratorTab::Mixed; QList allButtons = findChildren(); for (auto &allButton : allButtons) { @@ -540,9 +605,29 @@ void AcceleratorTab::update_threads() choice = AcceleratorTab::Kokkos; else if (button == "gpu") choice = AcceleratorTab::Gpu; + else if (button == "inteldouble") + prec = AcceleratorTab::Double; + else if (button == "intelmixed") + prec = AcceleratorTab::Mixed; + else if (button == "intelsingle") + prec = AcceleratorTab::Single; } } + auto *group = findChild("intelprec"); + if (choice == AcceleratorTab::Intel) { + group->setEnabled(true); + } else { + group->setEnabled(false); + } + + group = findChild("gpuchoice"); + if (choice == AcceleratorTab::Gpu) { + group->setEnabled(true); + } else { + group->setEnabled(false); + } + #if defined(_OPENMP) // The number of threads field is disabled and the value set to 1 for "None" and "Opt" choice auto *field = findChild("nthreads"); diff --git a/tools/lammps-gui/preferences.h b/tools/lammps-gui/preferences.h index da5b698b6e..507b87c4a3 100644 --- a/tools/lammps-gui/preferences.h +++ b/tools/lammps-gui/preferences.h @@ -74,9 +74,10 @@ class AcceleratorTab : public QWidget { public: explicit AcceleratorTab(QSettings *settings, LammpsWrapper *lammps, QWidget *parent = nullptr); enum { None, Opt, OpenMP, Intel, Kokkos, Gpu }; + enum { Double, Mixed, Single }; private slots: - void update_threads(); + void update_accel(); private: QSettings *settings;