more updates to preferences dialog and supporting code. almost done.

This commit is contained in:
Axel Kohlmeyer
2023-08-02 17:28:34 -04:00
parent 97d406f2ff
commit 2808a78822
6 changed files with 238 additions and 30 deletions

View File

@ -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];

View File

@ -94,7 +94,6 @@ private:
LammpsWrapper lammps;
std::string plugin_path;
bool is_running;
int nthreads;
QList<QString> recent_files;
std::vector<char *> lammps_args;
};

View File

@ -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
{

View File

@ -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;

View File

@ -13,9 +13,11 @@
#include "preferences.h"
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QDoubleValidator>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QIntValidator>
#include <QLabel>
#include <QLineEdit>
@ -26,11 +28,16 @@
#include "lammpswrapper.h"
#if defined(_OPENMP)
#include <omp.h>
#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<QRadioButton *> allButtons = tabWidget->findChildren<QRadioButton *>();
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<QLineEdit *>("nthreads");
if (field)
if (field->hasAcceptableInput()) settings->setValue("nthreads", field->text());
// store image width, height, and zoom
settings->beginGroup("snapshot");
field = tabWidget->findChild<QLineEdit *>("xsize");
if (field)
if (field->hasAcceptableInput()) settings->setValue("xsize", field->text());
field = tabWidget->findChild<QLineEdit *>("ysize");
if (field)
if (field->hasAcceptableInput()) settings->setValue("ysize", field->text());
field = tabWidget->findChild<QLineEdit *>("zoom");
if (field)
if (field->hasAcceptableInput()) settings->setValue("zoom", field->text());
settings->endGroup();
// general settings
QCheckBox *box = tabWidget->findChild<QCheckBox *>("echo");
if (box) settings->setValue("echo", box->isChecked() ? "1" : "0");
box = tabWidget->findChild<QCheckBox *>("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");
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);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(none);
layout->addWidget(kokkos);
layout->addWidget(intel);
layout->addWidget(openmp);
layout->addWidget(opt);
layout->addStretch(1);
setLayout(layout);
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:");
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);

View File

@ -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;