ViewerHostProfileSelectorWithWin.C 14.9 KB
Newer Older
hrchilds's avatar
hrchilds committed
1
2
/*****************************************************************************
*
brugger's avatar
   
brugger committed
3
* Copyright (c) 2000 - 2009, Lawrence Livermore National Security, LLC
hrchilds's avatar
hrchilds committed
4
* Produced at the Lawrence Livermore National Laboratory
brugger's avatar
   
brugger committed
5
* LLNL-CODE-400124
hrchilds's avatar
hrchilds committed
6
7
* All rights reserved.
*
brugger's avatar
   
brugger committed
8
* This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
hrchilds's avatar
hrchilds committed
9
10
11
12
13
14
15
16
17
18
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution  and  use  in  source  and  binary  forms,  with  or  without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of  source code must  retain the above  copyright notice,
*    this list of conditions and the disclaimer below.
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
brugger's avatar
   
brugger committed
19
20
21
*    documentation and/or other materials provided with the distribution.
*  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
*    be used to endorse or promote products derived from this software without
hrchilds's avatar
hrchilds committed
22
23
24
25
26
*    specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
brugger's avatar
   
brugger committed
27
28
29
* ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
* LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
* DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
hrchilds's avatar
hrchilds committed
30
31
32
33
34
35
36
37
38
* DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
* SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
* CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
* LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
* OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/

hrchilds's avatar
hrchilds committed
39
40
41
#include <ViewerHostProfileSelectorWithWin.h>

#include <HostProfileList.h>
42
#include <MachineProfile.h>
hrchilds's avatar
hrchilds committed
43
44
45
46
#include <ViewerSubject.h>

#include <stdio.h>

whitlocb's avatar
whitlocb committed
47
48
49
50
51
52
#include <QLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QListWidget>
#include <QSpinBox>
hrchilds's avatar
hrchilds committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

#include <DebugStream.h>

#include <string>
using std::string;
#include <vector>
using std::vector;

extern ViewerSubject *viewerSubject;

// ****************************************************************************
//  Constructor:  ViewerHostProfileSelectorWithWin::ViewerHostProfileSelectorWithWin
//
//  Notes:  
//    Taken from ViewerEngineChooser by Jeremy Meredith.
//
//  Programmer:  Kathleen Bonnell 
//  Creation:    February 5, 2003 
//
//  Modifications:
hrchilds's avatar
hrchilds committed
73
74
//   Kathleen Bonnell, Tue Jan 11 16:14:14 PST 2005
//   Set minimum for numNodes spinbox to 1.
hrchilds's avatar
hrchilds committed
75
//
hrchilds's avatar
hrchilds committed
76
77
78
//   Jeremy Meredith, Thu Sep 15 16:37:24 PDT 2005
//   Added machinefile for some mpich implementations.
//
79
80
81
//   Brad Whitlock, Tue Apr 29 15:07:23 PDT 2008
//   Added tr()'s
//
whitlocb's avatar
whitlocb committed
82
83
84
//   Brad Whitlock, Fri May 23 11:36:45 PDT 2008
//   Qt 4.
//
hrchilds's avatar
hrchilds committed
85
86
// ****************************************************************************

whitlocb's avatar
whitlocb committed
87
88
ViewerHostProfileSelectorWithWin::ViewerHostProfileSelectorWithWin(QWidget *parent)
    : QDialog(parent)
hrchilds's avatar
hrchilds committed
89
{
whitlocb's avatar
whitlocb committed
90
91
    setWindowModality(Qt::ApplicationModal);

hrchilds's avatar
hrchilds committed
92
93
    waitingOnUser = false;

hrchilds's avatar
hrchilds committed
94
95
    QVBoxLayout *topLayout = new QVBoxLayout(this);

whitlocb's avatar
whitlocb committed
96
97
    QGridLayout *layout = new QGridLayout;
    topLayout->addLayout(layout);
hrchilds's avatar
hrchilds committed
98
99
100
101
102
103
104
    layout->setMargin(10);
    layout->setSpacing(5);
    layout->setRowStretch(0, 100);
    layout->setRowStretch(1, 0);
    layout->setRowStretch(2, 0);
    layout->setRowStretch(3, 0);

whitlocb's avatar
whitlocb committed
105
106
107
108
    layout->setColumnStretch(0, 0);
    layout->setColumnStretch(1, 100);
    layout->setColumnStretch(2, 0);
    layout->setColumnStretch(3, 100);
hrchilds's avatar
hrchilds committed
109

whitlocb's avatar
whitlocb committed
110
    profiles = new QListWidget(this);
hrchilds's avatar
hrchilds committed
111
    profiles->setMinimumHeight(100);
whitlocb's avatar
whitlocb committed
112
113
    layout->addWidget(profiles, 0,0, 1,4);
    connect(profiles, SIGNAL(itemSelectionChanged()),
hrchilds's avatar
hrchilds committed
114
            this,     SLOT(newProfileSelected()));
115
    connect(profiles, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(accept()));
hrchilds's avatar
hrchilds committed
116

whitlocb's avatar
whitlocb committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    numProcsLabel = new QLabel(tr("Num procs"), this);
    numProcs = new QSpinBox(this);
    numProcs->setMinimum(1);
    numProcs->setMaximum(99999);
    layout->addWidget(numProcsLabel, 1,0);
    layout->addWidget(numProcs,      1,1);

    numNodesLabel = new QLabel(tr("Num nodes"), this);
    numNodes = new QSpinBox(this);
    numNodes->setMinimum(1);
    numNodes->setMaximum(99999);
    layout->addWidget(numNodesLabel, 1,2);
    layout->addWidget(numNodes,      1,3);

    bankNameLabel = new QLabel(tr("Bank"), this);
    bankName = new QLineEdit(this);
    layout->addWidget(bankNameLabel, 2,0);
    layout->addWidget(bankName,      2,1);

    timeLimitLabel = new QLabel(tr("Time limit"), this);
    timeLimit = new QLineEdit(this);
    layout->addWidget(timeLimitLabel, 2,2);
    layout->addWidget(timeLimit,      2,3);

    machinefileLabel = new QLabel(tr("Machine file"), this);
    machinefile = new QLineEdit(this);
    layout->addWidget(machinefileLabel, 3,0);
    layout->addWidget(machinefile,      3,1, 1,3);

    QHBoxLayout *buttonLayout = new QHBoxLayout;
    topLayout->addLayout(buttonLayout);
hrchilds's avatar
hrchilds committed
148
149
    buttonLayout->setMargin(10);

whitlocb's avatar
whitlocb committed
150
    okayButton = new QPushButton(tr("OK"), this);
hrchilds's avatar
hrchilds committed
151
152
153
154
155
    buttonLayout->addWidget(okayButton, 0);
    connect(okayButton, SIGNAL(clicked()), this, SLOT(accept()));

    buttonLayout->addStretch(100);

whitlocb's avatar
whitlocb committed
156
    cancelButton = new QPushButton(tr("Cancel"), this);
hrchilds's avatar
hrchilds committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    buttonLayout->addWidget(cancelButton, 0);
    connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
}

// ****************************************************************************
//  Destructor:  ViewerHostProfileSelectorWithWin::~ViewerHostProfileSelectorWithWin
//
//  Programmer:  Kathleen Bonnell 
//  Creation:    February 5, 2003 
//
// ****************************************************************************

ViewerHostProfileSelectorWithWin::~ViewerHostProfileSelectorWithWin()
{
}

// ****************************************************************************
//  Method:  ViewerHostProfileSelectorWithWin::SelectProfile
//
//  Purpose:
//    Selects a profile to use when launching an Engine.  Allows user
//    selection via the chooser unless 'skipChooser' is true. 
//
//  Notes:
//    Taken from ViewerEngineChooser by Jeremy Meredith.
//
//  Arguments:
//    hostProfileList  : a list of possible host profiles. 
//    hostName         : the host name
//    skipChooser      : option to completely avoid the chooser. 
//
//  Returns: true if valid profile was selected, false otherwise.
//   
//  Programmer:  Jeremy Meredith
//  Creation:    August 14, 2002
//
//  Modifications:
//    Jeremy Meredith, Sat Aug 17 10:59:48 PDT 2002
//    Added support for nowin mode.
//
//    Brad Whitlock, Wed Nov 27 13:39:50 PST 2002
//    I added code to set certain parallel options into the EngineProxy
//    so that they can be queried easily later.
//
//    Jeremy Meredith, Wed Dec 18 17:18:05 PST 2002
//    Added skip option so that we completely avoid the chooser.
//    Also added code to temporarily block socket signals to the viewer.
//    Not doing so was breaking synchronization with the CLI through
//    a race condition to grab the signals.
//
//    Kathleen Bonnell, Wed Feb  5 09:46:31 PST 2003
//    Extracted code from ViewerHostProfileSelector::GetNewEngine.
//
hrchilds's avatar
hrchilds committed
210
211
212
213
214
215
//    Jeremy Meredith, Tue Mar 23 13:18:27 PST 2004
//    Disabled the code to cache the profile.  With our big parallel machines, 
//    resources change so frequently that it will irritate users to assume
//    that they want the same number of processors every time the engine
//    launches.
//
hrchilds's avatar
hrchilds committed
216
217
218
//    Jeremy Meredith, Wed Oct 27 13:59:14 PDT 2004
//    Prevented recursion into QDialog::exec().  See VisIt00005532.
//
hrchilds's avatar
hrchilds committed
219
220
221
//    Jeremy Meredith, Thu Sep 15 16:37:24 PDT 2005
//    Added machinefile for some mpich implementations.
//
222
223
224
//    Brad Whitlock, Tue Apr 29 15:08:19 PDT 2008
//    Support for internationalization.
//
whitlocb's avatar
whitlocb committed
225
226
227
//    Brad Whitlock, Fri May 23 11:54:42 PDT 2008
//    Qt 4.
//
228
229
230
//    Jeremy Meredith, Thu Feb 18 15:25:27 EST 2010
//    Split HostProfile int MachineProfile and LaunchProfile.
//
231
232
233
//    Jeremy Meredith, Thu Feb 25 10:16:15 EST 2010
//    Adding debug info.
//
234
235
236
//    Jeremy Meredith, Fri Feb 26 18:14:55 EST 2010
//    Don't forget to block signals when you mess with the list.
//
237
238
239
240
241
//    Jeremy Meredith, Fri Mar  5 14:19:21 EST 2010
//    Actually, we don't want to block signals, as this sets up the
//    window correctly the first time.  Just don't set it to a bad
//    index before you set it to the right one.
//
hrchilds's avatar
hrchilds committed
242
243
244
245
246
247
248
// ****************************************************************************

bool 
ViewerHostProfileSelectorWithWin::SelectProfile(
    HostProfileList *hostProfileList, const string &hostName, bool skipChooser)
{
    int  i;
249
    QString title = tr("Select options for '%1'").arg(hostName.c_str());
whitlocb's avatar
whitlocb committed
250
    setWindowTitle(title);
hrchilds's avatar
hrchilds committed
251

252
    profile = MachineProfile();
253
    debug2 << "ViewerHostProfileSelectorWithWin::SelectProfile\n";
hrchilds's avatar
hrchilds committed
254
255
256
257

    if (skipChooser)
    {
        // do nothing; leave the profile completely blank
258
        debug2 << "   Exiting: told to skip\n";
hrchilds's avatar
hrchilds committed
259
260
261
262
    }
    else if (cachedProfile.count(hostName))
    {
        profile = cachedProfile[hostName];
263
        debug2 << "   Exiting: found cached\n";
hrchilds's avatar
hrchilds committed
264
265
266
    }
    else
    {
hrchilds's avatar
hrchilds committed
267
268
269
270
271
272
273
274
275
        //
        // If someone tries to do something while we already have the
        // selector open and waiting on a user, just pretend they didn't
        // want to launch one.  This will cause the new operations to fail,
        // but at least it won't recurse into the exec() call and crash.
        //
        if (waitingOnUser)
            return false;

hrchilds's avatar
hrchilds committed
276
277
278
279
280
281
        //
        // Check for a host profile for the hostName. If one exists, add
        // any arguments to the command line for the engine proxy.  If
        // more than one exists, let the user choose the profile and
        // some options.
        //
282
        MachineProfile *mp = hostProfileList->GetMachineProfileForHost(hostName);
hrchilds's avatar
hrchilds committed
283

284
        if (mp)
hrchilds's avatar
hrchilds committed
285
        {
286
            profile = *mp;
287
288
289
290
291
292
293
294
295
296
297
298
299
            debug2 << "   Got a machine profile for host '"<<hostName<<"'\n";
            debug2 << "     It has "<<profile.GetNumLaunchProfiles()
                   <<" launch profiles\n";
            for (int i=0; i<profile.GetNumLaunchProfiles(); i++)
            {
                debug2 << "        launch profile #"<<i<<" has parallel="
                     <<(profile.GetLaunchProfiles(i).GetParallel()?"true":"false")
                     <<endl;
            }
        }
        else
        {
            debug2 << "   Found no matching machine profiles\n";
hrchilds's avatar
hrchilds committed
300
301
        }
        
302
303
304
        if (profile.GetNumLaunchProfiles() > 1 ||
            (profile.GetNumLaunchProfiles() == 1 &&
             profile.GetLaunchProfiles(0).GetParallel()))
hrchilds's avatar
hrchilds committed
305
        {
306
307
            debug2 << "   Presenting a choice to the user.\n";

308
            profiles->blockSignals(true);
hrchilds's avatar
hrchilds committed
309
            profiles->clear();
310
            for (i=0; i<profile.GetNumLaunchProfiles(); i++)
hrchilds's avatar
hrchilds committed
311
            {
312
                profiles->addItem(profile.GetLaunchProfiles(i).GetProfileName().c_str());
hrchilds's avatar
hrchilds committed
313
            }
314
            profiles->blockSignals(false);
315
316
            if (profile.GetActiveProfile()>=0 &&
                profile.GetActiveProfile()<profile.GetNumLaunchProfiles())
hrchilds's avatar
hrchilds committed
317
            {
318
319
                // this signals the callback to set the default profile
                profiles->setCurrentRow(profile.GetActiveProfile());
hrchilds's avatar
hrchilds committed
320
            }
321
322
323
324
            else
            {
                profiles->setCurrentRow(0);
            }
hrchilds's avatar
hrchilds committed
325
326

            viewerSubject->BlockSocketSignals(true);
hrchilds's avatar
hrchilds committed
327
            waitingOnUser = true;
hrchilds's avatar
hrchilds committed
328
            bool rejected = (exec() == QDialog::Rejected);
hrchilds's avatar
hrchilds committed
329
            waitingOnUser = false;
hrchilds's avatar
hrchilds committed
330
331
332
333
334
335
336
            viewerSubject->BlockSocketSignals(false);

            if (rejected)
            {
                return false;
            }

337
338
339
340
341
            profile.GetActiveLaunchProfile()->SetNumProcessors(numProcs->value());
            profile.GetActiveLaunchProfile()->SetNumNodes(numNodes->value());
            profile.GetActiveLaunchProfile()->SetBank(bankName->text().toStdString());
            profile.GetActiveLaunchProfile()->SetTimeLimit(timeLimit->text().toStdString());
            profile.GetActiveLaunchProfile()->SetMachinefile(machinefile->text().toStdString());
hrchilds's avatar
hrchilds committed
342
        }
343
344
345
346
        else
        {
            debug2 << "   No need to present a choice to the user.\n";
        }
hrchilds's avatar
hrchilds committed
347
348

        // Save it for use later
hrchilds's avatar
hrchilds committed
349
350
351
352
353
354
355

        // DISABLED 3/23/04 JSM:  No!  This was causing more usability
        // issues than it solved.  With our big parallel machines, 
        // resources change so frequently that it will irritate a 
        // user to assume that they want the same number of processors
        // every time the engine launches.
        //cachedProfile[hostName] = profile;
hrchilds's avatar
hrchilds committed
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    }
    return true;
}


// ****************************************************************************
//  Method:  ViewerHostProfileSelectorWithWin::newProfileSelected
//
//  Purpose:
//    Qt slot for when a new profile is selected.
//    Change the selected profile and update the related widgets.
//
//  Arguments:
//    none
//
//  Programmer:  Jeremy Meredith
//  Creation:    August 14, 2002
//
//  Modifications:
//    Jeremy Meredith, Fri Jan 24 10:14:17 PST 2003
//    Made it grey out the other parallel options if the profile wasn't
//    parallel.
//
379
380
381
382
383
//    Jeremy Meredith, Thu Sep 15 16:37:24 PDT 2005
//    Added machinefile for some mpich implementations.
//
//    Jeremy Meredith, Thu Feb 18 15:25:27 EST 2010
//    Split HostProfile int MachineProfile and LaunchProfile.
hrchilds's avatar
hrchilds committed
384
//
385
386
387
//    Jeremy Meredith, Thu Feb 25 10:11:36 EST 2010
//    Fixed a bug where it didn't let the user change from the default profile.
//
hrchilds's avatar
hrchilds committed
388
389
390
391
392
// ****************************************************************************

void
ViewerHostProfileSelectorWithWin::newProfileSelected()
{
whitlocb's avatar
whitlocb committed
393
    int index = profiles->currentRow();
394
    if (index < 0 || index >= profile.GetNumLaunchProfiles())
hrchilds's avatar
hrchilds committed
395
396
        return;

397
    profile.SetActiveProfile(index);
398
399
    LaunchProfile &lp = profile.GetLaunchProfiles(index);
    bool parallel = lp.GetParallel();
hrchilds's avatar
hrchilds committed
400
401
402

    numProcsLabel->setEnabled(parallel);
    numProcs->setEnabled(parallel);
403
    numProcs->setValue(lp.GetNumProcessors());
hrchilds's avatar
hrchilds committed
404

405
406
407
    numNodesLabel->setEnabled(parallel && lp.GetNumNodesSet());
    numNodes->setEnabled(parallel && lp.GetNumNodesSet());
    numNodes->setValue(lp.GetNumNodes());
hrchilds's avatar
hrchilds committed
408

409
410
411
    bankNameLabel->setEnabled(parallel && lp.GetBankSet());
    bankName->setEnabled(parallel && lp.GetBankSet());
    bankName->setText(lp.GetBank().c_str());
hrchilds's avatar
hrchilds committed
412

413
414
415
    timeLimitLabel->setEnabled(parallel && lp.GetTimeLimitSet());
    timeLimit->setEnabled(parallel && lp.GetTimeLimitSet());
    timeLimit->setText(lp.GetTimeLimit().c_str());
hrchilds's avatar
hrchilds committed
416

417
418
419
    machinefileLabel->setEnabled(parallel && lp.GetMachinefileSet());
    machinefile->setEnabled(parallel && lp.GetMachinefileSet());
    machinefile->setText(lp.GetMachinefile().c_str());
hrchilds's avatar
hrchilds committed
420
421
422
}