mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
2010 lines
56 KiB
C++
2010 lines
56 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: $RCSfile$
|
|
|
|
Copyright (c) Kitware, Inc.
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "pqMemoryInspectorPanel.h"
|
|
#include "pqRemoteCommandDialog.h"
|
|
#include "ui_pqMemoryInspectorPanelForm.h"
|
|
using Ui::pqMemoryInspectorPanelForm;
|
|
|
|
// #define pqMemoryInspectorPanelDEBUG
|
|
|
|
// print a process table to stderr during initialization
|
|
// #define MIP_PROCESS_TABLE
|
|
|
|
#include "pqActiveObjects.h"
|
|
#include "pqServerManagerModel.h"
|
|
#include "pqApplicationCore.h"
|
|
#include "pqView.h"
|
|
#include "pqRenderView.h"
|
|
#include "vtkSMRenderViewProxy.h"
|
|
|
|
#include "vtkProcessModule.h"
|
|
#include "vtkPVSystemConfigInformation.h"
|
|
#include "vtkPVMemoryUseInformation.h"
|
|
#include "vtkPVEnableStackTraceSignalHandler.h"
|
|
#include "vtkPVDisableStackTraceSignalHandler.h"
|
|
#include "vtkSMSession.h"
|
|
#include "vtkSMSessionClient.h"
|
|
#include "vtkPVInformation.h"
|
|
#include "vtkClientServerStream.h"
|
|
|
|
#include <QDebug>
|
|
#include <QFont>
|
|
#include <QFontMetrics>
|
|
#include <QFormLayout>
|
|
#include <QFrame>
|
|
#include <QLabel>
|
|
#include <QMenu>
|
|
#include <QMessageBox>
|
|
#include <QPalette>
|
|
#include <QPoint>
|
|
#include <QProcess>
|
|
#include <QProgressBar>
|
|
#include <QProxyStyle>
|
|
#include <QSettings>
|
|
#include <QString>
|
|
#include <QStringList>
|
|
#include <QStyleFactory>
|
|
#include <QTreeWidgetItem>
|
|
#include <QTreeWidgetItemIterator>
|
|
|
|
#if QT_VERSION < 0x050000
|
|
#include <QPlastiqueStyle>
|
|
#endif
|
|
|
|
#include <map>
|
|
using std::map;
|
|
using std::pair;
|
|
#include <vector>
|
|
using std::vector;
|
|
#include <string>
|
|
using std::string;
|
|
#include <sstream>
|
|
using std::ostringstream;
|
|
using std::istringstream;
|
|
#include <iostream>
|
|
using std::cerr;
|
|
using std::endl;
|
|
using std::left;
|
|
using std::right;
|
|
#include <iomanip>
|
|
using std::setw;
|
|
using std::setfill;
|
|
#include <algorithm>
|
|
using std::min;
|
|
|
|
|
|
#define pqErrorMacro(estr)\
|
|
qDebug()\
|
|
<< "Error in:" << endl\
|
|
<< __FILE__ << ", line " << __LINE__ << endl\
|
|
<< "" estr << endl;
|
|
|
|
// User interface
|
|
//=============================================================================
|
|
class pqMemoryInspectorPanelUI
|
|
:
|
|
public Ui::pqMemoryInspectorPanelForm
|
|
{};
|
|
|
|
// QProgress bar makes use of integer type. Each power of 10
|
|
// greater than 100 result in a decimal place of precision in
|
|
// the UI.
|
|
#define MIP_PROGBAR_MAX 1000
|
|
|
|
// keys for tree items
|
|
enum {
|
|
ITEM_KEY_PROCESS_TYPE=Qt::UserRole,
|
|
ITEM_KEY_PVSERVER_TYPE, // vtkProcessModule::ProcessTypes
|
|
ITEM_KEY_PID, // long long
|
|
ITEM_KEY_HOST_NAME, // string, hostname
|
|
ITEM_KEY_MPI_RANK, // int
|
|
ITEM_KEY_HOST_OS, // descriptive string
|
|
ITEM_KEY_HOST_CPU, // descriptive string
|
|
ITEM_KEY_HOST_MEM, // descriptive string
|
|
ITEM_KEY_SYSTEM_TYPE // int (0 unix like, 1 win)
|
|
};
|
|
|
|
// data for tree items
|
|
enum {
|
|
ITEM_DATA_CLIENT_GROUP,
|
|
ITEM_DATA_CLIENT_HOST,
|
|
ITEM_DATA_CLIENT_RANK,
|
|
ITEM_DATA_SERVER_GROUP,
|
|
ITEM_DATA_SERVER_HOST,
|
|
ITEM_DATA_SERVER_RANK,
|
|
ITEM_DATA_UNIX_SYSTEM=0,
|
|
ITEM_DATA_WIN_SYSTEM=1
|
|
};
|
|
|
|
namespace
|
|
{
|
|
#if QT_VERSION >= 0x050000
|
|
// ****************************************************************************
|
|
QStyle *getMemoryUseWidgetStyle()
|
|
{
|
|
// this sets the style for the progress bar used to
|
|
// display % memory usage. If we didn't do this the
|
|
// display will look different on each OS. The ownership
|
|
// of the style does not change hands when it's set to
|
|
// the widget thus a single static instance is convenient.
|
|
static QStyle* style = QStyleFactory::create("fusion");
|
|
return style;
|
|
}
|
|
#else
|
|
// ****************************************************************************
|
|
QPlastiqueStyle *getMemoryUseWidgetStyle()
|
|
{
|
|
// this sets the style for the progress bar used to
|
|
// display % memory usage. If we didn't do this the
|
|
// display will look different on each OS. The ownership
|
|
// of the style does not change hands when it's set to
|
|
// the widget thus a single static instance is convenient.
|
|
static QPlastiqueStyle style;
|
|
return &style;
|
|
}
|
|
#endif
|
|
// ****************************************************************************
|
|
float getSystemWarningThreshold()
|
|
{
|
|
# ifdef WIN32
|
|
return 0.90f;
|
|
# else
|
|
return 0.80f;
|
|
# endif
|
|
}
|
|
|
|
// ****************************************************************************
|
|
float getSystemCriticalThreshold()
|
|
{
|
|
# ifdef WIN32
|
|
return 0.95f;
|
|
# else
|
|
return 0.90f;
|
|
# endif
|
|
}
|
|
|
|
// ****************************************************************************
|
|
float getProcessWarningThreshold()
|
|
{
|
|
return 0.70f;
|
|
}
|
|
|
|
// ****************************************************************************
|
|
float getProcessCriticalThreshold()
|
|
{
|
|
return 0.80f;
|
|
}
|
|
|
|
// ****************************************************************************
|
|
void setMemoryUseWidgetColor(
|
|
QPalette &palette,
|
|
float fracUsed,
|
|
float fracWarn,
|
|
float fracCrit)
|
|
{
|
|
(void)fracWarn;
|
|
|
|
if (fracUsed>fracCrit)
|
|
{
|
|
// danger -> red
|
|
//palette.setColor(QPalette::Highlight,QColor(232,40,40)); // bright
|
|
//palette.setColor(QPalette::Highlight,QColor(190,60,60)); // moderate
|
|
//palette.setColor(QPalette::Highlight,QColor(147,57,57)); // moderate balanced
|
|
palette.setColor(QPalette::Highlight,QColor(217,84,84)); // cdash red
|
|
}
|
|
/*
|
|
else
|
|
if (fracUsed>fracWarn)
|
|
{
|
|
//palette.setColor(QPalette::Highlight,QColor(219,219,80)); // moderate
|
|
palette.setColor(QPalette::Highlight,QColor(252,168,84)); // cdash yellow
|
|
}
|
|
*/
|
|
else
|
|
{
|
|
// ok -> green
|
|
//palette.setColor(QPalette::Highlight,QColor(66,232,20)); // bright
|
|
//palette.setColor(QPalette::Highlight,QColor(90,160,70)); // moderate
|
|
//palette.setColor(QPalette::Highlight,QColor(125,176,74));// cdash yellow
|
|
palette.setColor(QPalette::Highlight, Qt::darkGray);
|
|
}
|
|
}
|
|
|
|
// ****************************************************************************
|
|
void setWidgetContainerColor(QPalette &palette, int rank)
|
|
{
|
|
if (rank%2)
|
|
{
|
|
palette.setColor(QPalette::Base,QColor(250,250,250));
|
|
}
|
|
else
|
|
{
|
|
palette.setColor(QPalette::Base,QColor(237,237,237));
|
|
}
|
|
}
|
|
|
|
// ****************************************************************************
|
|
QString translateUnits(float memUse)
|
|
{
|
|
QString fmt("%1 %2");
|
|
|
|
float p210=pow(2.0,10.0);
|
|
float p220=pow(2.0,20.0);
|
|
float p230=pow(2.0,30.0);
|
|
float p240=pow(2.0,40.0);
|
|
float p250=pow(2.0,50.0);
|
|
|
|
// were dealing with kiB
|
|
memUse *= 1024;
|
|
|
|
if (memUse<p210)
|
|
{
|
|
return fmt.arg(memUse, 0,'f',2).arg("B");
|
|
}
|
|
else
|
|
if (memUse<p220)
|
|
{
|
|
return fmt.arg(memUse/p210, 0,'f',2).arg("KiB");
|
|
}
|
|
else
|
|
if (memUse<p230)
|
|
{
|
|
return fmt.arg(memUse/p220, 0,'f',2).arg("MiB");
|
|
}
|
|
else
|
|
if (memUse<p240)
|
|
{
|
|
return fmt.arg(memUse/p230, 0,'f',2).arg("GiB");
|
|
}
|
|
else
|
|
if (memUse<p250)
|
|
{
|
|
return fmt.arg(memUse/p240, 0,'f',2).arg("TiB");
|
|
}
|
|
|
|
return fmt.arg(memUse/p250, 0,'f',2).arg("PiB");
|
|
}
|
|
|
|
// ****************************************************************************
|
|
template<typename T>
|
|
void ClearVectorOfPointers(vector<T *> data)
|
|
{
|
|
size_t n=data.size();
|
|
for (size_t i=0; i<n; ++i)
|
|
{
|
|
if (data[i])
|
|
{
|
|
delete data[i];
|
|
data[i]=NULL;
|
|
}
|
|
}
|
|
data.clear();
|
|
}
|
|
|
|
// ****************************************************************************
|
|
void unescapeWhitespace(string &s, char escChar)
|
|
{
|
|
size_t n=s.size();
|
|
for (size_t i=0; i<n; ++i)
|
|
{
|
|
if (s[i]==escChar)
|
|
{
|
|
s[i]=' ';
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
/// data associated with an mpi rank
|
|
//=============================================================================
|
|
class RankData
|
|
{
|
|
public:
|
|
RankData(
|
|
int rank,
|
|
long long pid,
|
|
long long procMemoryUse,
|
|
long long hostMemoryUse,
|
|
long long procAvail);
|
|
|
|
~RankData();
|
|
|
|
void SetRank(int rank){ this->Rank=rank; }
|
|
int GetRank(){ return this->Rank; }
|
|
|
|
void SetPid(long long pid){ this->Pid=pid; }
|
|
long long GetPid(){ return this->Pid; }
|
|
|
|
void SetProcMemoryAvailable(long long capacity){ this->ProcMemoryAvailable=capacity; }
|
|
long long GetProcMemoryAvailable(){ return this->ProcMemoryAvailable; }
|
|
|
|
void SetProcMemoryUse(long long load){ this->ProcMemoryUse=load; }
|
|
long long GetProcMemoryUse(){ return this->ProcMemoryUse; }
|
|
|
|
void SetHostMemoryUse(long long load){ this->HostMemoryUse=load; }
|
|
long long GetHostMemoryUse(){ return this->HostMemoryUse; }
|
|
|
|
float GetProcMemoryUseFraction()
|
|
{ return (float)this->ProcMemoryUse/(float)this->ProcMemoryAvailable; }
|
|
|
|
QFrame *GetMemoryUseWidget(){ return this->WidgetContainer; }
|
|
|
|
void UpdateMemoryUseWidget();
|
|
void InitializeMemoryUseWidget();
|
|
|
|
void Print(ostream &os);
|
|
|
|
private:
|
|
void InitializeMemoryUseWidget(QProgressBar *&loadWidget);
|
|
|
|
private:
|
|
int Rank;
|
|
long long Pid;
|
|
long long ProcMemoryUse;
|
|
long long HostMemoryUse;
|
|
long long ProcMemoryAvailable;
|
|
QProgressBar *MemoryUseWidget;
|
|
QFrame *WidgetContainer;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
RankData::RankData(
|
|
int rank,
|
|
long long pid,
|
|
long long procMemoryUse,
|
|
long long hostMemoryUse,
|
|
long long procAvail)
|
|
:
|
|
Rank(rank),
|
|
Pid(pid),
|
|
ProcMemoryUse(procMemoryUse),
|
|
HostMemoryUse(hostMemoryUse),
|
|
ProcMemoryAvailable(procAvail)
|
|
{
|
|
this->InitializeMemoryUseWidget();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
RankData::~RankData()
|
|
{
|
|
delete this->WidgetContainer;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RankData::UpdateMemoryUseWidget()
|
|
{
|
|
float used = (float)this->GetProcMemoryUse();
|
|
float fracUsed = min(1.0f,this->GetProcMemoryUseFraction());
|
|
float percUsed = fracUsed*100.0f;
|
|
int progVal = (int)(fracUsed*MIP_PROGBAR_MAX);
|
|
|
|
this->MemoryUseWidget->setValue(progVal);
|
|
this->MemoryUseWidget->setFormat(
|
|
QString("%1 %2%").arg(::translateUnits(used)).arg(percUsed, 0,'f',2));
|
|
|
|
QPalette palette(this->MemoryUseWidget->palette());
|
|
::setMemoryUseWidgetColor(
|
|
palette,
|
|
fracUsed,
|
|
::getProcessWarningThreshold(),
|
|
::getProcessCriticalThreshold());
|
|
this->MemoryUseWidget->setPalette(palette);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RankData::InitializeMemoryUseWidget()
|
|
{
|
|
this->InitializeMemoryUseWidget(this->MemoryUseWidget);
|
|
|
|
QLabel *rank=new QLabel;
|
|
rank->setText(QString("%1").arg(this->Rank));
|
|
|
|
QFrame *vline=new QFrame;
|
|
vline->setFrameStyle(QFrame::VLine|QFrame::Plain);
|
|
|
|
QFrame *vline2=new QFrame;
|
|
vline2->setFrameStyle(QFrame::VLine|QFrame::Plain);
|
|
|
|
QLabel *pid=new QLabel;
|
|
pid->setText(QString("%1").arg(this->Pid));
|
|
|
|
QHBoxLayout *w=new QHBoxLayout;
|
|
w->addWidget(this->MemoryUseWidget);
|
|
w->setContentsMargins(2,2,2,2);
|
|
w->setSpacing(2);
|
|
|
|
QHBoxLayout *l=new QHBoxLayout;
|
|
l->addWidget(rank);
|
|
l->addWidget(vline);
|
|
l->addWidget(pid);
|
|
l->addWidget(vline2);
|
|
l->addLayout(w);
|
|
l->setContentsMargins(1,0,1,0);
|
|
l->setSpacing(0);
|
|
|
|
this->WidgetContainer=new QFrame;
|
|
this->WidgetContainer->setLayout(l);
|
|
this->WidgetContainer->setFrameStyle(QFrame::Box|QFrame::Plain);
|
|
this->WidgetContainer->setLineWidth(1);
|
|
QFont font(this->WidgetContainer->font());
|
|
font.setPointSize(8);
|
|
this->WidgetContainer->setFont(font);
|
|
|
|
QPalette palette(rank->palette());
|
|
::setWidgetContainerColor(palette, this->Rank);
|
|
|
|
rank->setPalette(palette);
|
|
rank->setAutoFillBackground(true);
|
|
|
|
pid->setPalette(palette);
|
|
pid->setAutoFillBackground(true);
|
|
|
|
QFontMetrics fontMet(font);
|
|
int rankWid=fontMet.width("555555");
|
|
rank->setMinimumWidth(rankWid);
|
|
rank->setMaximumWidth(rankWid);
|
|
|
|
int pidWid=fontMet.width("555555555");
|
|
pid->setMinimumWidth(pidWid);
|
|
pid->setMaximumWidth(pidWid);
|
|
|
|
this->UpdateMemoryUseWidget();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RankData::InitializeMemoryUseWidget(QProgressBar *&loadWidget)
|
|
{
|
|
loadWidget=new QProgressBar;
|
|
loadWidget->setStyle(::getMemoryUseWidgetStyle());
|
|
loadWidget->setMaximumHeight(15);
|
|
loadWidget->setMinimum(0);
|
|
loadWidget->setMaximum(MIP_PROGBAR_MAX);
|
|
QFont font(loadWidget->font());
|
|
font.setPointSize(8);
|
|
loadWidget->setFont(font);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RankData::Print(ostream &os)
|
|
{
|
|
os
|
|
<< "RankData(" << this << ")"
|
|
<< " Rank=" << this->Rank
|
|
<< " Pid=" << this->Pid
|
|
<< " ProcMemoryUse=" << this->ProcMemoryUse
|
|
<< " HostMemoryUse=" << this->HostMemoryUse
|
|
<< " ProcMemoryAvailable=" << this->ProcMemoryAvailable
|
|
<< " MemoryUseWidget=" << this->MemoryUseWidget
|
|
<< endl;
|
|
}
|
|
|
|
/// data associated with the host (a collection of ranks)
|
|
//=============================================================================
|
|
class HostData
|
|
{
|
|
public:
|
|
HostData();
|
|
HostData(string groupName,string hostName,long long memTotal, long long memAvail);
|
|
HostData(const HostData &other){ *this=other; }
|
|
const HostData &operator=(const HostData &other);
|
|
~HostData();
|
|
|
|
RankData *AddRankData(int rank, long long pid, long long procMemAvail);
|
|
RankData *GetRankData(int i);
|
|
void ClearRankData();
|
|
|
|
string &GetGroupName(){ return this->GroupName; }
|
|
string &GetHostName(){ return this->HostName; }
|
|
long long GetHostMemoryTotal(){ return this->HostMemoryTotal; }
|
|
long long GetHostMemoryAvailable(){ return this->HostMemoryAvailable; }
|
|
long long GetTotalSystemMemoryUse();
|
|
long long GetProcessGroupMemoryUse();
|
|
|
|
void SetTreeItem(QTreeWidgetItem *item){ this->TreeItem=item; }
|
|
QTreeWidgetItem *GetTreeItem(){ return this->TreeItem; }
|
|
|
|
QWidget *GetMemoryUseWidget(){ return (QWidget*)this->WidgetContainer; }
|
|
QProgressBar *GetTotalMemoryUseWidget(){ return this->TotalMemoryUseWidget; }
|
|
QProgressBar *GetGroupMemoryUseWidget(){ return this->GroupMemoryUseWidget; }
|
|
|
|
void InitializeMemoryUseWidget();
|
|
void InitializeMemoryUseWidget(QProgressBar *&loadWidget);
|
|
|
|
void UpdateMemoryUseWidget();
|
|
void UpdateMemoryUseWidget(
|
|
QProgressBar *loadWidget,
|
|
long long used,
|
|
float fracUsed,
|
|
float warnFrac,
|
|
float critFrac);
|
|
|
|
void Print(ostream &os);
|
|
|
|
private:
|
|
string GroupName;
|
|
string HostName;
|
|
long long HostMemoryTotal; // memory installed
|
|
long long HostMemoryAvailable; // memory available to us.
|
|
QProgressBar *TotalMemoryUseWidget; // for displaying all process's use
|
|
QProgressBar *GroupMemoryUseWidget; // for displaying only pv process's use
|
|
QFrame *WidgetContainer; // widget containing both all and proccess group
|
|
QTreeWidgetItem *TreeItem; // gui element
|
|
vector<RankData *> Ranks; // references to ranks local to this host
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
HostData::HostData()
|
|
:
|
|
GroupName(""),
|
|
HostName(""),
|
|
HostMemoryTotal(0),
|
|
HostMemoryAvailable(0)
|
|
{}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
HostData::HostData(
|
|
string groupName,
|
|
string hostName,
|
|
long long hostMemTotal,
|
|
long long hostMemAvail)
|
|
:
|
|
GroupName(groupName),
|
|
HostName(hostName),
|
|
HostMemoryTotal(hostMemTotal),
|
|
HostMemoryAvailable(hostMemAvail)
|
|
{
|
|
this->InitializeMemoryUseWidget();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
HostData::~HostData()
|
|
{
|
|
this->ClearRankData();
|
|
delete this->WidgetContainer;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const HostData &HostData::operator=(const HostData &other)
|
|
{
|
|
if (this==&other) return *this;
|
|
|
|
this->GroupName=other.GroupName;
|
|
this->HostName=other.HostName;
|
|
this->HostMemoryTotal=other.HostMemoryTotal;
|
|
this->HostMemoryAvailable=other.HostMemoryAvailable;
|
|
this->TotalMemoryUseWidget=other.TotalMemoryUseWidget;
|
|
this->GroupMemoryUseWidget=other.GroupMemoryUseWidget;
|
|
this->TreeItem=other.TreeItem;
|
|
this->Ranks=other.Ranks;
|
|
|
|
return *this;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
RankData *HostData::GetRankData(int i)
|
|
{
|
|
if ((size_t)i<this->Ranks.size())
|
|
{
|
|
return this->Ranks[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void HostData::ClearRankData()
|
|
{
|
|
::ClearVectorOfPointers<RankData>(this->Ranks);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
RankData *HostData::AddRankData(
|
|
int rank,
|
|
long long pid,
|
|
long long procMemAvail)
|
|
{
|
|
RankData *newRank=new RankData(rank,pid,0,0,procMemAvail);
|
|
this->Ranks.push_back(newRank);
|
|
return newRank;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
long long HostData::GetTotalSystemMemoryUse()
|
|
{
|
|
long long load=0;
|
|
if (this->Ranks.size())
|
|
{
|
|
load=this->Ranks[0]->GetHostMemoryUse();
|
|
}
|
|
return load;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
long long HostData::GetProcessGroupMemoryUse()
|
|
{
|
|
long long load=0;
|
|
size_t n=this->Ranks.size();
|
|
for (size_t i=0; i<n; ++i)
|
|
{
|
|
load+=this->Ranks[i]->GetProcMemoryUse();
|
|
}
|
|
return load;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void HostData::InitializeMemoryUseWidget()
|
|
{
|
|
this->InitializeMemoryUseWidget(this->TotalMemoryUseWidget);
|
|
this->InitializeMemoryUseWidget(this->GroupMemoryUseWidget);
|
|
|
|
QFormLayout *l=new QFormLayout;
|
|
l->setRowWrapPolicy(QFormLayout::DontWrapRows);
|
|
l->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
|
l->setFormAlignment(Qt::AlignHCenter|Qt::AlignTop);
|
|
l->setLabelAlignment(Qt::AlignRight);
|
|
l->setContentsMargins(2,2,2,2);
|
|
l->setSpacing(2);
|
|
|
|
l->addRow("System Total",this->TotalMemoryUseWidget);
|
|
l->addRow(this->GroupName.c_str(),this->GroupMemoryUseWidget);
|
|
|
|
QLabel *label=new QLabel;
|
|
label->setText(this->HostName.c_str());
|
|
|
|
QFrame *vline=new QFrame;
|
|
vline->setFrameStyle(QFrame::VLine|QFrame::Plain);
|
|
|
|
QHBoxLayout *h=new QHBoxLayout;
|
|
h->addWidget(label);
|
|
h->addWidget(vline);
|
|
h->addLayout(l);
|
|
h->setContentsMargins(1,0,1,0);
|
|
h->setSpacing(0);
|
|
|
|
this->WidgetContainer=new QFrame;
|
|
this->WidgetContainer->setLayout(h);
|
|
this->WidgetContainer->setFrameStyle(QFrame::Box|QFrame::Plain);
|
|
QFont font(this->WidgetContainer->font());
|
|
font.setPointSize(8);
|
|
this->WidgetContainer->setFont(font);
|
|
|
|
this->UpdateMemoryUseWidget();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void HostData::InitializeMemoryUseWidget(QProgressBar *&loadWidget)
|
|
{
|
|
loadWidget=new QProgressBar;
|
|
loadWidget->setStyle(::getMemoryUseWidgetStyle());
|
|
loadWidget->setMaximumHeight(15);
|
|
loadWidget->setMinimum(0);
|
|
loadWidget->setMaximum(MIP_PROGBAR_MAX);
|
|
QFont font(loadWidget->font());
|
|
font.setPointSize(8);
|
|
loadWidget->setFont(font);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void HostData::UpdateMemoryUseWidget()
|
|
{
|
|
long long load;
|
|
float frac;
|
|
|
|
load=this->GetTotalSystemMemoryUse();
|
|
frac=min(1.0f,(float)load/(float)this->HostMemoryTotal);
|
|
this->UpdateMemoryUseWidget(
|
|
this->TotalMemoryUseWidget,
|
|
load,
|
|
frac,
|
|
::getSystemWarningThreshold(),
|
|
::getSystemCriticalThreshold());
|
|
|
|
load=this->GetProcessGroupMemoryUse();
|
|
frac=min(1.0f,(float)load/(float)this->HostMemoryAvailable);
|
|
this->UpdateMemoryUseWidget(
|
|
this->GroupMemoryUseWidget,
|
|
load,
|
|
frac,
|
|
::getProcessWarningThreshold(),
|
|
::getProcessCriticalThreshold());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void HostData::UpdateMemoryUseWidget(
|
|
QProgressBar *loadWidget,
|
|
long long used,
|
|
float fracUsed,
|
|
float warnFrac,
|
|
float critFrac)
|
|
{
|
|
float percUsed = fracUsed*100.0f;
|
|
int progVal = (int)(fracUsed*MIP_PROGBAR_MAX);
|
|
|
|
loadWidget->setValue(progVal);
|
|
loadWidget->setFormat(
|
|
QString("%1 %2%").arg(::translateUnits(used)).arg(percUsed, 0,'f',2));
|
|
|
|
QPalette palette(loadWidget->palette());
|
|
::setMemoryUseWidgetColor(
|
|
palette,
|
|
fracUsed,
|
|
warnFrac,
|
|
critFrac);
|
|
loadWidget->setPalette(palette);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void HostData::Print(ostream &os)
|
|
{
|
|
os
|
|
<< "HostData(" << this << ")"
|
|
<< " HostName=" << this->HostName
|
|
<< " HostMemoryTotal=" << this->HostMemoryTotal
|
|
<< " TotalMemoryUseWidget=" << this->TotalMemoryUseWidget
|
|
<< " GroupMemoryUseWidget=" << this->GroupMemoryUseWidget
|
|
<< " WidgetContainer=" << this->WidgetContainer
|
|
<< " TreeItem=" << this->TreeItem
|
|
<< " Ranks=" << endl;
|
|
size_t nRanks=this->Ranks.size();
|
|
for (size_t i=0; i<nRanks; ++i)
|
|
{
|
|
this->Ranks[i]->Print(os);
|
|
}
|
|
os << endl;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
pqMemoryInspectorPanel::pqMemoryInspectorPanel(
|
|
QWidget* pWidget,
|
|
Qt::WindowFlags flags)
|
|
:
|
|
QWidget(pWidget,flags)
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::pqMemoryInspectorPanel" << endl;
|
|
#endif
|
|
|
|
this->ClientOnly=1;
|
|
this->ClientHost=0;
|
|
this->AutoUpdate=true;
|
|
this->UpdateEnabled=0;
|
|
|
|
// Construct Qt form.
|
|
this->Ui=new pqMemoryInspectorPanelUI;
|
|
this->Ui->setupUi(this);
|
|
this->Ui->updateMemUse->setIcon(QPixmap(":/pqWidgets/Icons/pqRedo24.png"));
|
|
|
|
// attempt initialization here before we begin to listen
|
|
// for event's that could trigger and update.
|
|
this->Initialize();
|
|
|
|
// listen for enable/disable auto update
|
|
QObject::connect(
|
|
this->Ui->autoUpdate,
|
|
SIGNAL(toggled(bool)),
|
|
this,
|
|
SLOT(SetAutoUpdate(bool)));
|
|
|
|
// listen for manual update request
|
|
QObject::connect(
|
|
this->Ui->updateMemUse,
|
|
SIGNAL(released()),
|
|
this,
|
|
SLOT(Update()));
|
|
|
|
// listen to context menu events
|
|
QObject::connect(
|
|
this->Ui->configView,
|
|
SIGNAL(customContextMenuRequested(const QPoint &)),
|
|
this,
|
|
SLOT(ConfigViewContextMenu(const QPoint &)));
|
|
this->Ui->configView->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
// connect to new views as they are created
|
|
pqServerManagerModel* smm
|
|
= pqApplicationCore::instance()->getServerManagerModel();
|
|
|
|
// listen for new views, we want to update after render is finished.
|
|
QObject::connect(
|
|
smm,
|
|
SIGNAL(viewAdded(pqView*)),
|
|
this,
|
|
SLOT(ConnectToView(pqView*)));
|
|
|
|
// listen to the active view for render completed events.
|
|
pqView* view=pqActiveObjects::instance().activeView();
|
|
if (view)
|
|
{
|
|
this->ConnectToView(view);
|
|
}
|
|
|
|
// listen to servers connecting and disconnecting
|
|
QObject::connect(
|
|
smm,
|
|
SIGNAL(serverAdded(pqServer*)),
|
|
this,
|
|
SLOT(ServerConnected()));
|
|
|
|
QObject::connect(
|
|
smm,
|
|
SIGNAL(finishedRemovingServer()),
|
|
this,
|
|
SLOT(ServerDisconnected()));
|
|
|
|
/*
|
|
// TODO -- not sure if these are useful, maybe for responding
|
|
// to python events?
|
|
QObject::connect(
|
|
smm,
|
|
SIGNAL(dataUpdated(pqPipelineSource*)),
|
|
this,
|
|
SLOT(EnableUpdate()));
|
|
|
|
QObject::connect(
|
|
smm,
|
|
SIGNAL(proxyAdded(pqProxy*)),
|
|
this,
|
|
SLOT(EnableUpdate()));
|
|
|
|
QObject::connect(
|
|
smm,
|
|
SIGNAL(proxRemoved(pqProxy*)),
|
|
this,
|
|
SLOT(EnableUpdate()));
|
|
*/
|
|
|
|
QPalette pal=this->Ui->configView->palette();
|
|
pal.setColor(QPalette::Highlight, Qt::lightGray);
|
|
this->Ui->configView->setPalette(pal);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
pqMemoryInspectorPanel::~pqMemoryInspectorPanel()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::~pqMemoryInspectorPanel" << endl;
|
|
#endif
|
|
|
|
this->ClearClient();
|
|
this->ClearServers();
|
|
|
|
delete this->Ui;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ClearClient()
|
|
{
|
|
if (this->ClientHost)
|
|
{
|
|
delete this->ClientHost;
|
|
}
|
|
this->ClientHost=0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ClearServer(
|
|
map<string,HostData *> &hosts,
|
|
vector<RankData *> &ranks)
|
|
{
|
|
map<string,HostData*>::iterator it=hosts.begin();
|
|
map<string,HostData*>::iterator end=hosts.end();
|
|
while (it!=end)
|
|
{
|
|
if ((*it).second)
|
|
{
|
|
delete (*it).second;
|
|
(*it).second=NULL;
|
|
}
|
|
++it;
|
|
}
|
|
hosts.clear();
|
|
ranks.clear();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ClearServers()
|
|
{
|
|
this->ClientOnly=1;
|
|
this->ClearServer(this->ServerHosts,this->ServerRanks);
|
|
this->ClearServer(this->DataServerHosts,this->DataServerRanks);
|
|
this->ClearServer(this->RenderServerHosts,this->RenderServerRanks);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ServerDisconnected()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel:;ServerDisconnected" << endl;
|
|
#endif
|
|
|
|
this->ClearClient();
|
|
this->ClearServers();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ServerConnected()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::ServerConnected" << endl;
|
|
#endif
|
|
|
|
this->Initialize();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ConnectToView(pqView *view)
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::ConnectToView" << endl;
|
|
#endif
|
|
|
|
// rendering triggers the update
|
|
QObject::connect(
|
|
view,
|
|
SIGNAL(endRender()),
|
|
this,
|
|
SLOT(RenderCompleted()));
|
|
|
|
// update only after data is changed
|
|
QObject::connect(
|
|
view,
|
|
SIGNAL(updateDataEvent()),
|
|
this,
|
|
SLOT(EnableUpdate()));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::showEvent(QShowEvent *e)
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::showEvent" << endl;
|
|
#endif
|
|
|
|
(void)e;
|
|
this->Update();
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::EnableUpdate()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::EnableUpdate" << endl;
|
|
#endif
|
|
|
|
this->UpdateEnabled=1;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::RenderCompleted()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::RenderCompleted" << endl;
|
|
#endif
|
|
|
|
if (!this->AutoUpdate || !this->isVisible() || !this->UpdateEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->Update();
|
|
return;
|
|
|
|
/*
|
|
// This code is for updating on endRender regardless of whether
|
|
// or not data was updated.it works better than updating only
|
|
// after data is udpated. however is disabled because it's slight
|
|
// over kill
|
|
if (!this->AutoUpdate || !this->isVisible())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// only going to respond to render view's events. other view's
|
|
// events may be useful to track but need to consider case by
|
|
// case and verify that we don't flood the server with update
|
|
// requests.
|
|
pqRenderView* view
|
|
= qobject_cast<pqRenderView*>(pqActiveObjects::instance().activeView());
|
|
|
|
if (view)
|
|
{
|
|
vtkSMRenderViewProxy *viewProxy
|
|
= dynamic_cast<vtkSMRenderViewProxy*>(view->getProxy());
|
|
if (viewProxy)
|
|
{
|
|
if (!viewProxy->LastRenderWasInteractive() && !this->PendingUpdate)
|
|
{
|
|
// there are two still renders after the last
|
|
// interactive render.
|
|
QTimer::singleShot(2000, this, SLOT(Update()));
|
|
this->PendingUpdate=1;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::InitializeServerGroup(
|
|
long long clientPid,
|
|
vtkPVSystemConfigInformation *configs,
|
|
int validProcessType,
|
|
QTreeWidgetItem *group,
|
|
string groupName,
|
|
map<string,HostData*> &hosts,
|
|
vector<RankData*> &ranks,
|
|
int &systemType)
|
|
{
|
|
size_t nConfigs=configs->GetSize();
|
|
for (size_t i=0; i<nConfigs; ++i)
|
|
{
|
|
// assume that we get what we ask for and nothing more
|
|
// but verify that it's not the builtin
|
|
long long pid=configs->GetPid(i);
|
|
if (pid==clientPid)
|
|
{
|
|
// must be the builtin, do not duplicate.
|
|
continue;
|
|
}
|
|
int processType=configs->GetProcessType(i);
|
|
if (processType!=validProcessType)
|
|
{
|
|
// it's not the correct type.
|
|
continue;
|
|
}
|
|
string os=configs->GetOSDescriptor(i);
|
|
string cpu=configs->GetCPUDescriptor(i);
|
|
string mem=configs->GetMemoryDescriptor(i);
|
|
string hostName=configs->GetHostName(i);
|
|
systemType=configs->GetSystemType(i);
|
|
int rank=configs->GetRank(i);
|
|
long long hostMemoryTotal=configs->GetHostMemoryTotal(i);
|
|
long long hostMemoryAvailable=configs->GetHostMemoryAvailable(i);
|
|
long long procMemoryAvailable=configs->GetProcMemoryAvailable(i);
|
|
|
|
// it's useful to have hostname's rank's and pid's in
|
|
// the terminal. if the client hangs you can attach
|
|
// gdb and see where it's stuck without a lot of effort
|
|
|
|
#ifdef MIP_PROCESS_TABLE
|
|
cerr
|
|
<< setw(32) << hostName
|
|
<< setw(16) << pid
|
|
<< setw(8) << rank << endl
|
|
<< setw(1);
|
|
#endif
|
|
|
|
// host
|
|
HostData *serverHost=NULL;
|
|
|
|
pair<string,HostData*> ins(hostName,(HostData*)0);
|
|
pair<map<string,HostData*>::iterator,bool> ret;
|
|
ret=hosts.insert(ins);
|
|
if (ret.second)
|
|
{
|
|
// new host
|
|
serverHost=new HostData(groupName,hostName,hostMemoryTotal,hostMemoryAvailable);
|
|
ret.first->second=serverHost;
|
|
|
|
QTreeWidgetItem *serverHostItem=new QTreeWidgetItem(group);
|
|
serverHostItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
serverHostItem->setExpanded(true);
|
|
serverHostItem->setData(0,ITEM_KEY_PROCESS_TYPE,QVariant(ITEM_DATA_SERVER_HOST));
|
|
serverHostItem->setData(0,ITEM_KEY_PVSERVER_TYPE,QVariant(processType));
|
|
serverHostItem->setData(0,ITEM_KEY_SYSTEM_TYPE,QVariant(systemType));
|
|
serverHostItem->setData(0,ITEM_KEY_HOST_NAME,QVariant(hostName.c_str()));
|
|
serverHostItem->setData(0,ITEM_KEY_HOST_OS,QString(os.c_str()));
|
|
serverHostItem->setData(0,ITEM_KEY_HOST_CPU,QString(cpu.c_str()));
|
|
serverHostItem->setData(0,ITEM_KEY_HOST_MEM,QString(mem.c_str()));
|
|
this->Ui->configView->setItemWidget(serverHostItem,0,serverHost->GetMemoryUseWidget());
|
|
|
|
serverHost->SetTreeItem(serverHostItem);
|
|
}
|
|
else
|
|
{
|
|
serverHost=ret.first->second;
|
|
}
|
|
// rank
|
|
RankData *serverRank=serverHost->AddRankData(rank,pid,procMemoryAvailable);
|
|
ranks.push_back(serverRank);
|
|
|
|
QTreeWidgetItem *serverRankItem=new QTreeWidgetItem(serverHost->GetTreeItem());
|
|
serverRankItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
serverRankItem->setExpanded(false);
|
|
serverRankItem->setData(0,ITEM_KEY_PROCESS_TYPE,QVariant(ITEM_DATA_SERVER_RANK));
|
|
serverRankItem->setData(0,ITEM_KEY_PVSERVER_TYPE,QVariant(processType));
|
|
serverRankItem->setData(0,ITEM_KEY_HOST_NAME,QVariant(hostName.c_str()));
|
|
serverRankItem->setData(0,ITEM_KEY_PID,QVariant(pid));
|
|
serverRankItem->setData(0,ITEM_KEY_SYSTEM_TYPE,QVariant(systemType));
|
|
this->Ui->configView->setItemWidget(serverRankItem,0,serverRank->GetMemoryUseWidget());
|
|
}
|
|
|
|
// prune off the group if there were none added.
|
|
if (group->childCount()==0)
|
|
{
|
|
int idx=this->Ui->configView->indexOfTopLevelItem(group);
|
|
if (idx>=0)
|
|
{
|
|
this->Ui->configView->takeTopLevelItem(idx);
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int pqMemoryInspectorPanel::Initialize()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::Initialize" << endl;
|
|
#endif
|
|
|
|
this->ClearClient();
|
|
this->ClearServers();
|
|
|
|
this->ClientSystemType=0;
|
|
this->ServerSystemType=0;
|
|
this->DataServerSystemType=0;
|
|
this->RenderServerSystemType=0;
|
|
|
|
this->StackTraceOnClient=0;
|
|
this->StackTraceOnServer=0;
|
|
this->StackTraceOnDataServer=0;
|
|
this->StackTraceOnRenderServer=0;
|
|
|
|
this->Ui->configView->clear();
|
|
|
|
pqServer* server = pqActiveObjects::instance().activeServer();
|
|
if (!server)
|
|
{
|
|
// this is not necessarilly an error as the panel may be created
|
|
// before the server is connected.
|
|
return 0;
|
|
}
|
|
|
|
// client
|
|
QTreeWidgetItem *clientGroup=new QTreeWidgetItem(this->Ui->configView);
|
|
clientGroup->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
clientGroup->setExpanded(true);
|
|
clientGroup->setData(0,ITEM_KEY_PROCESS_TYPE,QVariant(ITEM_DATA_CLIENT_GROUP));
|
|
|
|
QWidget *groupWidget=this->NewGroupWidget("client",":/pqWidgets/Icons/pqClient32.png");
|
|
this->Ui->configView->setItemWidget(clientGroup,0,groupWidget);
|
|
|
|
vtkSMSession *session=NULL;
|
|
vtkPVSystemConfigInformation *configs=NULL;
|
|
|
|
configs=vtkPVSystemConfigInformation::New();
|
|
session=server->session();
|
|
session->GatherInformation(vtkPVSession::CLIENT,configs,0);
|
|
|
|
size_t nConfigs=configs->GetSize();
|
|
if (nConfigs!=1)
|
|
{
|
|
pqErrorMacro("There should always be one client.");
|
|
return 0;
|
|
}
|
|
|
|
long long clientPid=configs->GetPid(0);
|
|
|
|
this->ClientHost
|
|
= new HostData(
|
|
"paraview",
|
|
configs->GetHostName(0),
|
|
configs->GetHostMemoryTotal(0),
|
|
configs->GetHostMemoryAvailable(0));
|
|
|
|
this->ClientHost->AddRankData(
|
|
0,
|
|
configs->GetPid(0),
|
|
configs->GetProcMemoryAvailable(0));
|
|
|
|
this->ClientSystemType=configs->GetSystemType(0);
|
|
|
|
QTreeWidgetItem *clientHostItem=new QTreeWidgetItem(clientGroup);
|
|
clientHostItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
clientHostItem->setExpanded(true);
|
|
clientHostItem->setData(0,ITEM_KEY_PROCESS_TYPE,QVariant(ITEM_DATA_CLIENT_HOST));
|
|
clientHostItem->setData(0,ITEM_KEY_PVSERVER_TYPE,QVariant(configs->GetProcessType(0)));
|
|
clientHostItem->setData(0,ITEM_KEY_SYSTEM_TYPE,QVariant(configs->GetSystemType(0)));
|
|
clientHostItem->setData(0,ITEM_KEY_HOST_OS,QString(configs->GetOSDescriptor(0)));
|
|
clientHostItem->setData(0,ITEM_KEY_HOST_CPU,QString(configs->GetCPUDescriptor(0)));
|
|
clientHostItem->setData(0,ITEM_KEY_HOST_MEM,QString(configs->GetMemoryDescriptor(0)));
|
|
clientHostItem->setData(0,ITEM_KEY_HOST_NAME,QVariant(configs->GetHostName(0)));
|
|
clientHostItem->setData(0,ITEM_KEY_PID,QVariant(configs->GetPid(0)));
|
|
this->Ui->configView->setItemWidget(clientHostItem,0,this->ClientHost->GetMemoryUseWidget());
|
|
|
|
configs->Delete();
|
|
|
|
#ifdef MIP_PROCESS_TABLE
|
|
// print a process table to the terminal.
|
|
cerr
|
|
<< endl
|
|
<< setw(32) << "Host"
|
|
<< setw(16) << "Pid"
|
|
<< setw(8) << "Rank"
|
|
<< endl
|
|
<< left << setw(56) << setfill('=') << "client" << endl
|
|
<< right<< setw(1) << setfill(' ')
|
|
<< setw(32) << configs->GetFullyQualifiedDomainName(0)
|
|
<< setw(16) << configs->GetPid(0)
|
|
<< setw(8) << "x" << endl
|
|
<< setfill(' ') << setw(1);
|
|
#endif
|
|
|
|
// collect info from the server(s)
|
|
|
|
configs=vtkPVSystemConfigInformation::New();
|
|
|
|
vtkPVSystemConfigInformation *dsconfigs=vtkPVSystemConfigInformation::New();
|
|
session->GatherInformation(vtkPVSession::DATA_SERVER,dsconfigs,0);
|
|
configs->AddInformation(dsconfigs);
|
|
dsconfigs->Delete();
|
|
|
|
// don't attempt to communicate with a render server if it's
|
|
// not connected which results in a duplicated gather as in that
|
|
// case comm is routed to the data server.
|
|
if (session->GetRenderClientMode()==vtkSMSession::RENDERING_SPLIT)
|
|
{
|
|
vtkPVSystemConfigInformation *rsconfigs=vtkPVSystemConfigInformation::New();
|
|
session->GatherInformation(vtkPVSession::RENDER_SERVER,rsconfigs,0);
|
|
configs->AddInformation(rsconfigs);
|
|
rsconfigs->Delete();
|
|
}
|
|
|
|
nConfigs=configs->GetSize();
|
|
if (nConfigs>0)
|
|
{
|
|
configs->Sort();
|
|
|
|
// servers
|
|
#ifdef MIP_PROCESS_TABLE
|
|
cerr
|
|
<< left << setw(56) << setfill('=') << "server" << endl
|
|
<< right << setw(1) << setfill(' ');
|
|
#endif
|
|
QTreeWidgetItem *group=NULL;
|
|
group = new QTreeWidgetItem(this->Ui->configView);
|
|
group->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
group->setExpanded(true);
|
|
group->setData(0,ITEM_KEY_PROCESS_TYPE,QVariant(ITEM_DATA_SERVER_GROUP));
|
|
|
|
groupWidget=this->NewGroupWidget("server",":/pqWidgets/Icons/pqDataServer32.png");
|
|
this->Ui->configView->addTopLevelItem(group);
|
|
this->Ui->configView->setItemWidget(group,0,groupWidget);
|
|
|
|
this->InitializeServerGroup(
|
|
clientPid,
|
|
configs,
|
|
vtkProcessModule::PROCESS_SERVER,
|
|
group,
|
|
"pvserver",
|
|
this->ServerHosts,
|
|
this->ServerRanks,
|
|
this->ServerSystemType);
|
|
|
|
// dataservers
|
|
#ifdef MIP_PROCESS_TABLE
|
|
cerr
|
|
<< left << setw(56) << setfill('=') << "data server" << endl
|
|
<< right << setw(1) << setfill(' ');
|
|
#endif
|
|
group = new QTreeWidgetItem(this->Ui->configView);
|
|
group->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
group->setExpanded(true);
|
|
group->setData(0,ITEM_KEY_PROCESS_TYPE,QVariant(ITEM_DATA_SERVER_GROUP));
|
|
|
|
groupWidget=this->NewGroupWidget("data server",":/pqWidgets/Icons/pqDataServer32.png");
|
|
this->Ui->configView->addTopLevelItem(group);
|
|
this->Ui->configView->setItemWidget(group,0,groupWidget);
|
|
|
|
this->InitializeServerGroup(
|
|
clientPid,
|
|
configs,
|
|
vtkProcessModule::PROCESS_DATA_SERVER,
|
|
group,
|
|
"pvdataserver",
|
|
this->DataServerHosts,
|
|
this->DataServerRanks,
|
|
this->DataServerSystemType);
|
|
|
|
// renderservers
|
|
#ifdef MIP_PROCESS_TABLE
|
|
cerr
|
|
<< left << setw(56) << setfill('=') << "render server" << endl
|
|
<< right << setw(1) << setfill(' ');
|
|
#endif
|
|
group = new QTreeWidgetItem(this->Ui->configView);
|
|
group->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
group->setExpanded(true);
|
|
group->setData(0,ITEM_KEY_PROCESS_TYPE,QVariant(ITEM_DATA_SERVER_GROUP));
|
|
|
|
groupWidget=this->NewGroupWidget("render server",":/pqWidgets/Icons/pqDataServer32.png");
|
|
this->Ui->configView->addTopLevelItem(group);
|
|
this->Ui->configView->setItemWidget(group,0,groupWidget);
|
|
|
|
this->InitializeServerGroup(
|
|
clientPid,
|
|
configs,
|
|
vtkProcessModule::PROCESS_RENDER_SERVER,
|
|
group,
|
|
"pvrenderserver",
|
|
this->RenderServerHosts,
|
|
this->RenderServerRanks,
|
|
this->RenderServerSystemType);
|
|
|
|
#ifdef MIP_PROCESS_TABLE
|
|
cerr << setw(56) << setfill('=') << "=" << endl << setw(1) << setfill(' ');
|
|
#endif
|
|
}
|
|
configs->Delete();
|
|
|
|
//
|
|
this->ClientOnly=0;
|
|
if ( (this->RenderServerHosts.size()==0)
|
|
&& (this->DataServerHosts.size()==0)
|
|
&& (this->ServerHosts.size()==0))
|
|
{
|
|
this->ClientOnly=1;
|
|
}
|
|
else
|
|
{
|
|
// update host load to reflect all of its ranks.
|
|
map<string,HostData*>::iterator it;
|
|
map<string,HostData*>::iterator end;
|
|
it=this->DataServerHosts.begin();
|
|
end=this->DataServerHosts.end();
|
|
while (it!=end)
|
|
{
|
|
it->second->UpdateMemoryUseWidget();
|
|
++it;
|
|
}
|
|
|
|
it=this->RenderServerHosts.begin();
|
|
end=this->RenderServerHosts.end();
|
|
while (it!=end)
|
|
{
|
|
it->second->UpdateMemoryUseWidget();
|
|
++it;
|
|
}
|
|
}
|
|
|
|
//
|
|
this->Ui->configView->resizeColumnToContents(0);
|
|
this->Ui->configView->resizeColumnToContents(1);
|
|
|
|
// fecth the remote memory usage
|
|
this->Update();
|
|
|
|
// don't expand by default when there are a lot of
|
|
// sever hosts
|
|
if ( (this->RenderServerHosts.size()>1)
|
|
|| (this->DataServerHosts.size()>1)
|
|
|| (this->ServerHosts.size()>2) )
|
|
{
|
|
this->ShowOnlyNodes();
|
|
}
|
|
else
|
|
{
|
|
this->ShowAllRanks();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::Update()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::Update" << endl;
|
|
#endif
|
|
|
|
pqServer* server = pqActiveObjects::instance().activeServer();
|
|
if (!server)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!this->Initialized() && !this->Initialize())
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->UpdateRanks();
|
|
this->UpdateHosts();
|
|
|
|
this->PendingUpdate=0;
|
|
this->UpdateEnabled=0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::UpdateRanks()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::UpdateRanks" << endl;
|
|
#endif
|
|
|
|
pqServer* server = pqActiveObjects::instance().activeServer();
|
|
if (!server)
|
|
{
|
|
pqErrorMacro("failed to get active server");
|
|
return;
|
|
}
|
|
|
|
// fectch latest numbers
|
|
vtkSMSession *session=NULL;
|
|
vtkPVMemoryUseInformation *infos=NULL;
|
|
size_t nInfos=0;
|
|
|
|
// client
|
|
infos=vtkPVMemoryUseInformation::New();
|
|
session=server->session();
|
|
session->GatherInformation(vtkPVSession::CLIENT,infos,0);
|
|
|
|
nInfos=infos->GetSize();
|
|
if (nInfos==0)
|
|
{
|
|
pqErrorMacro("failed to get client info");
|
|
return;
|
|
}
|
|
|
|
RankData *clientRank=this->ClientHost->GetRankData(0);
|
|
clientRank->SetProcMemoryUse(infos->GetProcMemoryUse(0));
|
|
clientRank->SetHostMemoryUse(infos->GetHostMemoryUse(0));
|
|
clientRank->UpdateMemoryUseWidget();
|
|
|
|
infos->Delete();
|
|
|
|
if (this->ClientOnly)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// servers
|
|
infos=vtkPVMemoryUseInformation::New();
|
|
|
|
vtkPVMemoryUseInformation *dsinfos=vtkPVMemoryUseInformation::New();
|
|
session->GatherInformation(vtkPVSession::DATA_SERVER,dsinfos,0);
|
|
infos->AddInformation(dsinfos);
|
|
dsinfos->Delete();
|
|
|
|
// don't attempt to communicate with a render server if it's
|
|
// not connected which results in a duplicated gather as in that
|
|
// case comm is routed to the data server.
|
|
if (session->GetRenderClientMode()==vtkSMSession::RENDERING_SPLIT)
|
|
{
|
|
vtkPVMemoryUseInformation *rsinfos=vtkPVMemoryUseInformation::New();
|
|
session->GatherInformation(vtkPVSession::RENDER_SERVER,rsinfos,0);
|
|
infos->AddInformation(rsinfos);
|
|
rsinfos->Delete();
|
|
}
|
|
|
|
nInfos=infos->GetSize();
|
|
for (size_t i=0; i<nInfos; ++i)
|
|
{
|
|
int rank=infos->GetRank((int)i);
|
|
long long procUse=infos->GetProcMemoryUse((int)i);
|
|
long long hostUse=infos->GetHostMemoryUse((int)i);
|
|
|
|
switch (infos->GetProcessType((int)i))
|
|
{
|
|
case vtkProcessModule::PROCESS_SERVER:
|
|
if (this->ServerRanks.size())
|
|
{
|
|
this->ServerRanks[rank]->SetProcMemoryUse(procUse);
|
|
this->ServerRanks[rank]->SetHostMemoryUse(hostUse);
|
|
this->ServerRanks[rank]->UpdateMemoryUseWidget();
|
|
}
|
|
break;
|
|
|
|
case vtkProcessModule::PROCESS_DATA_SERVER:
|
|
if (this->DataServerRanks.size())
|
|
{
|
|
this->DataServerRanks[rank]->SetProcMemoryUse(procUse);
|
|
this->DataServerRanks[rank]->SetHostMemoryUse(hostUse);
|
|
this->DataServerRanks[rank]->UpdateMemoryUseWidget();
|
|
}
|
|
break;
|
|
|
|
case vtkProcessModule::PROCESS_RENDER_SERVER:
|
|
if (this->RenderServerRanks.size())
|
|
{
|
|
this->RenderServerRanks[rank]->SetProcMemoryUse(procUse);
|
|
this->RenderServerRanks[rank]->SetHostMemoryUse(hostUse);
|
|
this->RenderServerRanks[rank]->UpdateMemoryUseWidget();
|
|
}
|
|
break;
|
|
|
|
case vtkProcessModule::PROCESS_INVALID:
|
|
case vtkProcessModule::PROCESS_CLIENT:
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
infos->Delete();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::UpdateHosts()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::UpdateHosts" << endl;
|
|
#endif
|
|
|
|
this->ClientHost->UpdateMemoryUseWidget();
|
|
|
|
if (this->ClientOnly)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->UpdateHosts(this->ServerHosts);
|
|
this->UpdateHosts(this->DataServerHosts);
|
|
this->UpdateHosts(this->RenderServerHosts);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::UpdateHosts(map<string,HostData*> &hosts)
|
|
{
|
|
// update host laod to reflect all of its ranks.
|
|
map<string,HostData*>::iterator it=hosts.begin();
|
|
map<string,HostData*>::iterator end=hosts.end();
|
|
while (it!=end)
|
|
{
|
|
(*it).second->UpdateMemoryUseWidget();
|
|
++it;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::EnableStackTraceOnClient(bool enable)
|
|
{
|
|
this->EnableStackTrace(enable,vtkPVSession::CLIENT);
|
|
this->StackTraceOnClient=enable;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::EnableStackTraceOnServer(bool enable)
|
|
{
|
|
this->EnableStackTrace(enable,vtkPVSession::DATA_SERVER);
|
|
this->StackTraceOnServer=enable;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::EnableStackTraceOnDataServer(bool enable)
|
|
{
|
|
this->EnableStackTrace(enable,vtkPVSession::DATA_SERVER);
|
|
this->StackTraceOnDataServer=enable;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::EnableStackTraceOnRenderServer(bool enable)
|
|
{
|
|
this->EnableStackTrace(enable,vtkPVSession::RENDER_SERVER);
|
|
this->StackTraceOnRenderServer=enable;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::EnableStackTrace(bool enable, int group)
|
|
{
|
|
pqServer* server = pqActiveObjects::instance().activeServer();
|
|
if (!server)
|
|
{
|
|
pqErrorMacro("Failed to get the server");
|
|
return;
|
|
}
|
|
|
|
if (enable)
|
|
{
|
|
vtkPVEnableStackTraceSignalHandler *esh
|
|
= vtkPVEnableStackTraceSignalHandler::New();
|
|
|
|
server->session()->GatherInformation(group,esh,0);
|
|
}
|
|
else
|
|
{
|
|
vtkPVDisableStackTraceSignalHandler *dsh
|
|
= vtkPVDisableStackTraceSignalHandler::New();
|
|
|
|
server->session()->GatherInformation(group,dsh,0);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ExecuteRemoteCommand()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::ExecCommand" << endl;
|
|
#endif
|
|
|
|
|
|
QTreeWidgetItem *item=this->Ui->configView->currentItem();
|
|
if (item)
|
|
{
|
|
bool ok;
|
|
int type=item->data(0,ITEM_KEY_PROCESS_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
|
|
// treate the client group like a rank.
|
|
if (type==ITEM_DATA_CLIENT_GROUP)
|
|
{
|
|
item=item->child(0);
|
|
if (item==NULL) return;
|
|
type=item->data(0,ITEM_KEY_PROCESS_TYPE).toInt();
|
|
}
|
|
// treate the client host like a rank.
|
|
if (type==ITEM_DATA_CLIENT_HOST)
|
|
{
|
|
type=ITEM_DATA_CLIENT_RANK;
|
|
}
|
|
|
|
switch (type)
|
|
{
|
|
case ITEM_DATA_CLIENT_RANK:
|
|
case ITEM_DATA_SERVER_RANK:
|
|
{
|
|
string host((const char *)item->data(0,ITEM_KEY_HOST_NAME).toString().toLatin1());
|
|
string pid((const char *)item->data(0,ITEM_KEY_PID).toString().toLatin1());
|
|
|
|
int serverSystemType=item->data(0,ITEM_KEY_SYSTEM_TYPE).toInt();
|
|
|
|
bool localServer=(this->ClientHost->GetHostName()==host);
|
|
if (localServer)
|
|
{
|
|
serverSystemType=-1;
|
|
}
|
|
|
|
// select and configure a command
|
|
pqRemoteCommandDialog dialog(this,0,this->ClientSystemType,serverSystemType);
|
|
|
|
dialog.SetActiveHost(host);
|
|
dialog.SetActivePid(pid);
|
|
|
|
if (dialog.exec()==QDialog::Accepted)
|
|
{
|
|
string command=dialog.GetCommand();
|
|
|
|
string tmp;
|
|
|
|
QString exe;
|
|
QStringList args;
|
|
|
|
istringstream is(command);
|
|
|
|
is >> tmp;
|
|
::unescapeWhitespace(tmp,'^');
|
|
exe = tmp.c_str();
|
|
|
|
while (is.good())
|
|
{
|
|
is >> tmp;
|
|
::unescapeWhitespace(tmp,'^');
|
|
args << tmp.c_str();
|
|
}
|
|
|
|
QProcess *proc = new QProcess(this);
|
|
QObject::connect(
|
|
proc, SIGNAL(error(QProcess::ProcessError)),
|
|
this, SLOT(RemoteCommandFailed(QProcess::ProcessError)));
|
|
proc->setProcessChannelMode(QProcess::ForwardedChannels);
|
|
proc->closeWriteChannel();
|
|
proc->startDetached(exe,args);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
QMessageBox ebx(
|
|
QMessageBox::Information,
|
|
"Error",
|
|
"No process selected. Select a specific process first by "
|
|
"clicking on its entry in the tree view widget.");
|
|
ebx.exec();
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QMessageBox ebx(
|
|
QMessageBox::Information,
|
|
"Error",
|
|
"No process selected. Select a specific process first by "
|
|
"clicking on its entry in the tree view widget.");
|
|
ebx.exec();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::RemoteCommandFailed(
|
|
QProcess::ProcessError code)
|
|
{
|
|
switch (code)
|
|
{
|
|
case QProcess::FailedToStart:
|
|
qCritical() <<
|
|
"The process failed to start. Either the invoked program is missing, "
|
|
"or you may have insufficient permissions to invoke the program.";
|
|
break;
|
|
|
|
case QProcess::Crashed:
|
|
qCritical() << "The process crashed some time after starting successfully.";
|
|
break;
|
|
|
|
default:
|
|
qCritical() << "Process failed with error";
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ShowOnlyNodes()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::ShowOnlyNodes" << endl;
|
|
#endif
|
|
|
|
this->Ui->configView->collapseAll();
|
|
|
|
QTreeWidgetItem *item;
|
|
QTreeWidgetItemIterator it(this->Ui->configView);
|
|
while ((item=*it)!=(QTreeWidgetItem*)0)
|
|
{
|
|
bool ok;
|
|
int type=item->data(0,ITEM_KEY_PROCESS_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
switch (type)
|
|
{
|
|
case ITEM_DATA_CLIENT_GROUP:
|
|
case ITEM_DATA_SERVER_GROUP:
|
|
case ITEM_DATA_CLIENT_HOST:
|
|
item->setExpanded(true);
|
|
break;
|
|
|
|
case ITEM_DATA_SERVER_HOST:
|
|
item->setExpanded(false);
|
|
break;
|
|
|
|
case ITEM_DATA_CLIENT_RANK:
|
|
case ITEM_DATA_SERVER_RANK:
|
|
break;
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ShowAllRanks()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::ShowAllRanks" << endl;
|
|
#endif
|
|
|
|
this->Ui->configView->expandAll();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ShowHostPropertiesDialog()
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::ShowHostPropertiesDialog" << endl;
|
|
#endif
|
|
|
|
QTreeWidgetItem *item=this->Ui->configView->currentItem();
|
|
if (!item)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int type=item->data(0,ITEM_KEY_PROCESS_TYPE).toInt();
|
|
|
|
// treate the client group like a host.
|
|
if (type==ITEM_DATA_CLIENT_GROUP)
|
|
{
|
|
item=item->child(0);
|
|
if (item==NULL) return;
|
|
type=item->data(0,ITEM_KEY_PROCESS_TYPE).toInt();
|
|
}
|
|
|
|
if ( (type==ITEM_DATA_CLIENT_HOST)
|
|
|| (type==ITEM_DATA_SERVER_HOST) )
|
|
{
|
|
QString host=item->data(0,ITEM_KEY_HOST_NAME).toString();
|
|
QString os=item->data(0,ITEM_KEY_HOST_OS).toString();
|
|
QString cpu=item->data(0,ITEM_KEY_HOST_CPU).toString();
|
|
QString mem=item->data(0,ITEM_KEY_HOST_MEM).toString();
|
|
|
|
QString descr;
|
|
descr+="<h2>";
|
|
descr+=(type==ITEM_DATA_CLIENT_HOST?"Client":"Server");
|
|
descr+=" System Properties</h2><hr><table>";
|
|
descr+="<tr><td><b>Host:</b></td><td>";
|
|
descr+=host;
|
|
descr+="</td></tr>";
|
|
descr+="<tr><td><b>OS:</b></td><td>";
|
|
descr+=os;
|
|
descr+="</td></tr>";
|
|
descr+="<tr><td><b>CPU:</b></td><td>";
|
|
descr+=cpu;
|
|
descr+="</td></tr>";
|
|
descr+="<tr><td><b>Memory:</b></td><td>";
|
|
descr+=mem;
|
|
descr+="</td></tr></table><hr>";
|
|
|
|
QMessageBox props(QMessageBox::Information,"",descr,QMessageBox::Ok,this);
|
|
props.exec();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::ConfigViewContextMenu(const QPoint &position)
|
|
{
|
|
#if defined pqMemoryInspectorPanelDEBUG
|
|
cerr << ":::::pqMemoryInspectorPanel::ConfigContextMenu" << endl;
|
|
#endif
|
|
|
|
QMenu context;
|
|
|
|
QTreeWidgetItem * item=this->Ui->configView->itemAt(position);
|
|
if (item)
|
|
{
|
|
bool ok;
|
|
int procType=item->data(0,ITEM_KEY_PROCESS_TYPE).toInt(&ok);
|
|
if (!ok) { return; }
|
|
switch(procType)
|
|
{
|
|
case ITEM_DATA_CLIENT_GROUP:
|
|
{
|
|
QTreeWidgetItem *child=item->child(0);
|
|
if (child==NULL) return;
|
|
context.addAction("properties...",this,SLOT(ShowHostPropertiesDialog()));
|
|
int sysType=child->data(0,ITEM_KEY_SYSTEM_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
if (sysType==ITEM_DATA_UNIX_SYSTEM)
|
|
{
|
|
int serverType=child->data(0,ITEM_KEY_PVSERVER_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
|
|
this->AddEnableStackTraceMenuAction(serverType,context);
|
|
context.addAction("remote command...",this,SLOT(ExecuteRemoteCommand()));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITEM_DATA_SERVER_GROUP:
|
|
{
|
|
context.addAction("show only nodes",this,SLOT(ShowOnlyNodes()));
|
|
context.addAction("show all ranks",this,SLOT(ShowAllRanks()));
|
|
|
|
QTreeWidgetItem *child=item->child(0);
|
|
if (child==NULL) return;
|
|
int sysType=child->data(0,ITEM_KEY_SYSTEM_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
int serverType=child->data(0,ITEM_KEY_PVSERVER_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
if (sysType==ITEM_DATA_UNIX_SYSTEM)
|
|
{
|
|
this->AddEnableStackTraceMenuAction(serverType,context);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITEM_DATA_CLIENT_HOST:
|
|
case ITEM_DATA_CLIENT_RANK:
|
|
{
|
|
context.addAction("properties...",this,SLOT(ShowHostPropertiesDialog()));
|
|
int sysType=item->data(0,ITEM_KEY_SYSTEM_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
if (sysType==ITEM_DATA_UNIX_SYSTEM)
|
|
{
|
|
context.addAction("remote command...",this,SLOT(ExecuteRemoteCommand()));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITEM_DATA_SERVER_HOST:
|
|
{
|
|
context.addAction("properties...",this,SLOT(ShowHostPropertiesDialog()));
|
|
}
|
|
break;
|
|
|
|
case ITEM_DATA_SERVER_RANK:
|
|
{
|
|
context.addAction("show only nodes",this,SLOT(ShowOnlyNodes()));
|
|
context.addAction("show all ranks",this,SLOT(ShowAllRanks()));
|
|
|
|
int sysType=item->data(0,ITEM_KEY_SYSTEM_TYPE).toInt(&ok);
|
|
if (!ok) return;
|
|
if (sysType==ITEM_DATA_UNIX_SYSTEM)
|
|
{
|
|
context.addAction("remote command...",this,SLOT(ExecuteRemoteCommand()));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
context.exec(this->Ui->configView->mapToGlobal(position));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void pqMemoryInspectorPanel::AddEnableStackTraceMenuAction(
|
|
int serverType,
|
|
QMenu &context)
|
|
{
|
|
QAction *action=new QAction(this);
|
|
action->setText("stack trace signal handler");
|
|
action->setCheckable(true);
|
|
switch (serverType)
|
|
{
|
|
case vtkProcessModule::PROCESS_CLIENT:
|
|
action->setChecked(this->StackTraceOnClient);
|
|
connect(action,
|
|
SIGNAL(toggled(bool)),
|
|
this,
|
|
SLOT(EnableStackTraceOnClient(bool)));
|
|
break;
|
|
|
|
case vtkProcessModule::PROCESS_SERVER:
|
|
action->setChecked(this->StackTraceOnServer);
|
|
connect(action,
|
|
SIGNAL(toggled(bool)),
|
|
this,
|
|
SLOT(EnableStackTraceOnServer(bool)));
|
|
break;
|
|
|
|
case vtkProcessModule::PROCESS_DATA_SERVER:
|
|
action->setChecked(this->StackTraceOnDataServer);
|
|
connect(action,
|
|
SIGNAL(toggled(bool)),
|
|
this,
|
|
SLOT(EnableStackTraceOnDataServer(bool)));
|
|
break;
|
|
|
|
case vtkProcessModule::PROCESS_RENDER_SERVER:
|
|
action->setChecked(this->StackTraceOnRenderServer);
|
|
connect(action,
|
|
SIGNAL(toggled(bool)),
|
|
this,
|
|
SLOT(EnableStackTraceOnRenderServer(bool)));
|
|
break;
|
|
}
|
|
context.addAction(action);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
QWidget *pqMemoryInspectorPanel::NewGroupWidget(string name, string icon)
|
|
{
|
|
QHBoxLayout *hlayout=new QHBoxLayout;
|
|
|
|
QLabel *label=new QLabel;
|
|
label->setPixmap(QPixmap(icon.c_str()));
|
|
label->setToolTip(name.c_str());
|
|
hlayout->addWidget(label);
|
|
|
|
label=new QLabel;
|
|
label->setText(name.c_str());
|
|
hlayout->addWidget(label);
|
|
hlayout->addStretch(-1);
|
|
|
|
QFrame *frame=new QFrame;
|
|
frame->setLayout(hlayout);
|
|
QFont ffont(frame->font());
|
|
ffont.setPointSize(9);
|
|
ffont.setBold(true);
|
|
frame->setFont(ffont);
|
|
|
|
return frame;
|
|
}
|