1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #include "CudaSupportSettingsController.h"
23 
24 #include <QCheckBox>
25 #include <QLabel>
26 #include <QLayout>
27 
28 #include <U2Algorithm/CudaGpuRegistry.h>
29 
30 #include <U2Core/AppContext.h>
31 #include <U2Core/AppResources.h>
32 
33 namespace U2 {
34 
CudaSupportSettingsPageController(const QString & _displayMsg,QObject * p)35 CudaSupportSettingsPageController::CudaSupportSettingsPageController(const QString &_displayMsg, QObject *p /* = 0 */)
36     : AppSettingsGUIPageController(tr("CUDA"), CudaSupportSettingsPageId, p), displayMsg(_displayMsg) {
37 }
38 
39 const QString CudaSupportSettingsPageController::helpPageId = QString("444");
40 
getSavedState()41 AppSettingsGUIPageState *CudaSupportSettingsPageController::getSavedState() {
42     QList<CudaGpuModel *> registeredGpus = AppContext::getCudaGpuRegistry()->getRegisteredGpus();
43     CudaSupportSettingsPageState *s = new CudaSupportSettingsPageState(registeredGpus.size());
44     for (int i = 0, end = s->enabledGpus.size(); i < end; ++i) {
45         s->enabledGpus[i] = registeredGpus.at(i)->isEnabled();
46     }
47 
48     return s;
49 }
50 
saveState(AppSettingsGUIPageState * _s)51 void CudaSupportSettingsPageController::saveState(AppSettingsGUIPageState *_s) {
52     QList<CudaGpuModel *> registeredGpus = AppContext::getCudaGpuRegistry()->getRegisteredGpus();
53     CudaSupportSettingsPageState *s = qobject_cast<CudaSupportSettingsPageState *>(_s);
54 
55     // saving state of enabled/disabled GPUs into registry
56     for (int i = 0, end = s->enabledGpus.size(); i < end; ++i) {
57         registeredGpus[i]->setEnabled(s->enabledGpus[i]);
58     }
59 
60     // increasing/decreasing maxuse of according resource
61     int totalEnabled = s->enabledGpus.count(true);
62     AppResourceSemaphore *gpuResource = dynamic_cast<AppResourceSemaphore *>(AppResourcePool::instance()->getResource(RESOURCE_CUDA_GPU));
63     if (gpuResource) {
64         gpuResource->setMaxUse(totalEnabled);
65     }  // else - resource was not registered, nothing to do.
66 }
67 
createWidget(AppSettingsGUIPageState * state)68 AppSettingsGUIPageWidget *CudaSupportSettingsPageController::createWidget(AppSettingsGUIPageState *state) {
69     CudaSupportSettingsPageWidget *w = new CudaSupportSettingsPageWidget(displayMsg, this);
70     w->setState(state);
71     return w;
72 }
73 
CudaSupportSettingsPageState(int num_gpus)74 CudaSupportSettingsPageState::CudaSupportSettingsPageState(int num_gpus) {
75     assert(num_gpus >= 0);
76     enabledGpus.resize(num_gpus);
77 }
78 
79 const static char *gpusDiscoveredText =
80     "The following CUDA-enabled GPUs are detected.<br>\
81     Check the GPUs to use for accelerating algorithms computations.";
82 
83 const static char *noGpusDiscoveredText = "No CUDA-enabled GPU detected.";
84 
CudaSupportSettingsPageWidget(const QString & _msg,CudaSupportSettingsPageController *)85 CudaSupportSettingsPageWidget::CudaSupportSettingsPageWidget(const QString &_msg, CudaSupportSettingsPageController * /*ctrl*/)
86     : onlyMsg(_msg) {
87     if (!onlyMsg.isEmpty()) {
88         // just display the centered warning message
89         QHBoxLayout *hLayout = new QHBoxLayout(this);
90         QLabel *msgLabel = new QLabel(onlyMsg, this);
91         msgLabel->setAlignment(Qt::AlignLeft);
92 
93         hLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
94         hLayout->addWidget(msgLabel);
95         hLayout->addStretch();
96         setLayout(hLayout);
97     } else {
98         // everything is OK - adding info about all available GPUs
99 
100         QVBoxLayout *vLayout = new QVBoxLayout(this);
101 
102         QList<CudaGpuModel *> gpus = AppContext::getCudaGpuRegistry()->getRegisteredGpus();
103         const QString &actualText = gpus.empty() ? tr(noGpusDiscoveredText) : tr(gpusDiscoveredText);
104         QLabel *gpusDiscoveredLabel = new QLabel(actualText, this);
105         vLayout->addWidget(gpusDiscoveredLabel);
106 
107         foreach (CudaGpuModel *m, gpus) {
108             vLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
109             QHBoxLayout *hLayout = new QHBoxLayout(this);
110 
111             QString gpuText = m->getName() + " " + QString::number(m->getGlobalMemorySizeBytes() / (1024 * 1024)) + " Mb";
112             QCheckBox *check = new QCheckBox(gpuText, this);
113 
114             check->setChecked(true);
115 
116             gpuEnableChecks.push_back(check);
117             hLayout->addWidget(check);
118             vLayout->addLayout(hLayout);
119         }
120         setLayout(vLayout);
121     }
122 }
123 
setState(AppSettingsGUIPageState * _state)124 void CudaSupportSettingsPageWidget::setState(AppSettingsGUIPageState *_state) {
125     CudaSupportSettingsPageState *state = qobject_cast<CudaSupportSettingsPageState *>(_state);
126     assert(state->enabledGpus.size() == gpuEnableChecks.size());
127 
128     for (int i = 0, end = state->enabledGpus.size(); i < end; ++i) {
129         gpuEnableChecks.at(i)->setChecked(state->enabledGpus.at(i));
130     }
131 }
132 
getState(QString &) const133 AppSettingsGUIPageState *CudaSupportSettingsPageWidget::getState(QString & /*err*/) const {
134     CudaSupportSettingsPageState *state = new CudaSupportSettingsPageState(gpuEnableChecks.size());
135 
136     assert(state->enabledGpus.size() == gpuEnableChecks.size());
137     for (int i = 0, end = state->enabledGpus.size(); i < end; ++i) {
138         state->enabledGpus[i] = gpuEnableChecks.at(i)->isChecked();
139     }
140     return state;
141 }
142 
143 }  // namespace U2
144