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 // restorge and initialize settings
QSettings 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) #if defined(_OPENMP)
// use maximum number of available threads unless OMP_NUM_THREADS was set // 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 _WIN32
if (!getenv("OMP_NUM_THREADS")) { if (!getenv("OMP_NUM_THREADS")) {
_putenv_s("OMP_NUM_THREADS", std::to_string(nthreads).c_str()); _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); setenv("OMP_NUM_THREADS", std::to_string(nthreads).c_str(), 0);
#endif #endif
#else #else
nthreads = settings.value("nthreads", 1).toInt(); int nthreads = settings.value("nthreads", 1).toInt();
#endif #endif
settings.setValue("nthreads", QString::number(nthreads));
const char *tmpdir = getenv("TMPDIR"); const char *tmpdir = getenv("TMPDIR");
if (!tmpdir) tmpdir = getenv("TMP"); 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("LAMMPS-GUI"));
lammps_args.push_back(mystrdup("-log")); lammps_args.push_back(mystrdup("-log"));
lammps_args.push_back(mystrdup("none")); lammps_args.push_back(mystrdup("none"));
// lammps_args.push_back(mystrdup("-suffix"));
// lammps_args.push_back(mystrdup("omp"));
setWindowIcon(QIcon(":/lammps-icon-128x128.png")); setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
#if (__APPLE__) #if (__APPLE__)
@ -431,9 +432,11 @@ void LammpsGui::run_done()
void LammpsGui::run_buffer() void LammpsGui::run_buffer()
{ {
QSettings settings;
progress->setValue(0); progress->setValue(0);
dirstatus->hide(); dirstatus->hide();
progress->show(); progress->show();
int nthreads = settings.value("nthreads", 1).toInt();
status->setText(QString("Running LAMMPS with %1 thread(s)...").arg(nthreads)); status->setText(QString("Running LAMMPS with %1 thread(s)...").arg(nthreads));
status->repaint(); status->repaint();
start_lammps(); start_lammps();
@ -620,18 +623,61 @@ void LammpsGui::preferences()
{ {
Preferences prefs(&lammps); Preferences prefs(&lammps);
if (prefs.exec() == QDialog::Accepted) { if (prefs.exec() == QDialog::Accepted) {
// must delete LAMMPS instance after setting may be changed so we can apply different
// extract and apply settings as needed // suffixes
lammps.close();
} }
} }
void LammpsGui::start_lammps() 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(); char **args = lammps_args.data();
int narg = lammps_args.size(); int narg = lammps_args.size();
lammps.open(narg, args); 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()) { if (lammps.has_error()) {
constexpr int BUFLEN = 1024; constexpr int BUFLEN = 1024;
char errorbuf[BUFLEN]; char errorbuf[BUFLEN];

View File

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

View File

@ -151,6 +151,24 @@ void LammpsWrapper::finalize()
#endif #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) #if defined(LAMMPS_GUI_USE_PLUGIN)
bool LammpsWrapper::has_plugin() const bool LammpsWrapper::has_plugin() const
{ {

View File

@ -34,6 +34,8 @@ public:
bool is_running(); bool is_running();
bool has_error() const; bool has_error() const;
int get_last_error_message(char *errorbuf, int buflen); 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 load_lib(const char *lammpslib);
bool has_plugin() const; bool has_plugin() const;

View File

@ -13,9 +13,11 @@
#include "preferences.h" #include "preferences.h"
#include <QCheckBox>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QDoubleValidator> #include <QDoubleValidator>
#include <QGroupBox> #include <QGroupBox>
#include <QHBoxLayout>
#include <QIntValidator> #include <QIntValidator>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
@ -26,11 +28,16 @@
#include "lammpswrapper.h" #include "lammpswrapper.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
Preferences::Preferences(LammpsWrapper *_lammps, QWidget *parent) : Preferences::Preferences(LammpsWrapper *_lammps, QWidget *parent) :
QDialog(parent), tabWidget(new QTabWidget), QDialog(parent), tabWidget(new QTabWidget),
buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)), buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)),
settings(new QSettings), lammps(_lammps) settings(new QSettings), lammps(_lammps)
{ {
tabWidget->addTab(new GeneralTab(settings), "General Settings");
tabWidget->addTab(new AcceleratorTab(settings, lammps), "Accelerators"); tabWidget->addTab(new AcceleratorTab(settings, lammps), "Accelerators");
tabWidget->addTab(new SnapshotTab(settings), "Snapshot Image"); tabWidget->addTab(new SnapshotTab(settings), "Snapshot Image");
@ -42,7 +49,7 @@ Preferences::Preferences(LammpsWrapper *_lammps, QWidget *parent) :
layout->addWidget(buttonBox); layout->addWidget(buttonBox);
setLayout(layout); setLayout(layout);
setWindowTitle("LAMMPS-GUI - Preferences"); setWindowTitle("LAMMPS-GUI - Preferences");
resize(400, 320); resize(500, 400);
} }
Preferences::~Preferences() Preferences::~Preferences()
@ -56,46 +63,172 @@ void Preferences::accept()
{ {
// store all data in settings class // store all data in settings class
// and then confirm accepting // 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(); 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) : AcceleratorTab::AcceleratorTab(QSettings *_settings, LammpsWrapper *_lammps, QWidget *parent) :
QWidget(parent), settings(_settings), lammps(_lammps) QWidget(parent), settings(_settings), lammps(_lammps)
{ {
QGroupBox *accelerator = new QGroupBox("Choose Accelerator"); auto *mainLayout = new QHBoxLayout;
QRadioButton *none = new QRadioButton("&None"); auto *accelerator = new QGroupBox("Choose Accelerator:");
QRadioButton *kokkos = new QRadioButton("&Kokkos"); auto *none = new QRadioButton("&None");
QRadioButton *intel = new QRadioButton("&Intel"); auto *opt = new QRadioButton("O&pt");
QRadioButton *openmp = new QRadioButton("&OpenMP"); auto *openmp = new QRadioButton("&OpenMP");
QRadioButton *opt = new QRadioButton("O&pt"); auto *intel = new QRadioButton("&Intel");
auto *kokkos = new QRadioButton("&Kokkos");
auto *gpu = new QRadioButton("&GPU");
none->setChecked(true); auto *buttonLayout = new QVBoxLayout;
QVBoxLayout *layout = new QVBoxLayout; buttonLayout->addWidget(none);
layout->addWidget(none); buttonLayout->addWidget(opt);
layout->addWidget(kokkos); buttonLayout->addWidget(openmp);
layout->addWidget(intel); buttonLayout->addWidget(intel);
layout->addWidget(openmp); buttonLayout->addWidget(kokkos);
layout->addWidget(opt); buttonLayout->addWidget(gpu);
layout->addStretch(1); buttonLayout->addStretch(1);
setLayout(layout); 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) : SnapshotTab::SnapshotTab(QSettings *_settings, QWidget *parent) :
QWidget(parent), settings(_settings) QWidget(parent), settings(_settings)
{ {
QGridLayout *grid = new QGridLayout; auto *grid = new QGridLayout;
auto *xsize = new QLabel("Image width:"); auto *xsize = new QLabel("Image width:");
auto *ysize = new QLabel("Image height:"); auto *ysize = new QLabel("Image height:");
auto *zoom = new QLabel("Zoom factor:"); auto *zoom = new QLabel("Zoom factor:");
auto *xval = new QLineEdit(settings->value("xsize", "800").toString()); settings->beginGroup("snapshot");
auto *yval = new QLineEdit(settings->value("ysize", "600").toString()); auto *xval = new QLineEdit(settings->value("xsize", "800").toString());
auto *zval = new QLineEdit(settings->value("zoom", "1.0").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); auto *intval = new QIntValidator(100, 100000, this);
xval->setValidator(intval); xval->setValidator(intval);
xval->setObjectName("xsize");
yval->setValidator(intval); yval->setValidator(intval);
yval->setObjectName("ysize");
zval->setValidator(new QDoubleValidator(0.01, 100.0, 100, this)); zval->setValidator(new QDoubleValidator(0.01, 100.0, 100, this));
zval->setObjectName("zoom");
grid->addWidget(xsize, 0, 0); grid->addWidget(xsize, 0, 0);
grid->addWidget(ysize, 1, 0); grid->addWidget(ysize, 1, 0);

View File

@ -30,7 +30,7 @@ public:
protected slots: protected slots:
void accept() override; void accept() override;
private: private:
QTabWidget *tabWidget; QTabWidget *tabWidget;
QDialogButtonBox *buttonBox; QDialogButtonBox *buttonBox;
@ -40,12 +40,22 @@ private:
// individual tabs // individual tabs
class GeneralTab : public QWidget {
Q_OBJECT
public:
explicit GeneralTab(QSettings *settings, QWidget *parent = nullptr);
private:
QSettings *settings;
};
class AcceleratorTab : public QWidget { class AcceleratorTab : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit AcceleratorTab(QSettings *settings, LammpsWrapper *lammps, QWidget *parent = nullptr); explicit AcceleratorTab(QSettings *settings, LammpsWrapper *lammps, QWidget *parent = nullptr);
enum { None, Intel, Kokkos, OpenMP, Opt }; enum { None, Opt, OpenMP, Intel, Kokkos, Gpu };
private: private:
QSettings *settings; QSettings *settings;