Commit c23194f9 authored by cyrush's avatar cyrush
Browse files

added vtk debug mode

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@1962 18c085ea-50e0-402c-830e-de6fd14e8384
parent 91a9f3a6
......@@ -186,6 +186,10 @@ NewHandler(void)
// Kathleen Bonnell, Wed Aug 22 18:00:57 PDT 2007
// On Windows, write timings and log files to User's directory.
//
// Cyrus Harrison, Tue Sep 4 10:54:59 PDT 2007
// If -vtk-debug is specified make sure the debug level is at least 1
// for the engine
//
// ****************************************************************************
void
......@@ -197,7 +201,7 @@ Init::Initialize(int &argc, char *argv[], int r, int n, bool strip, bool sigs)
#else
bool usePid = false;
#endif
bool vtk_debug = false;
bool enableTimings = false;
for (i=1; i<argc; i++)
{
......@@ -232,6 +236,10 @@ Init::Initialize(int &argc, char *argv[], int r, int n, bool strip, bool sigs)
{
usePid = true;
}
else if (strcmp("-vtk-debug", argv[i]) == 0)
{
vtk_debug = true;
}
else if (strcmp("-timing", argv[i]) == 0 ||
strcmp("-timings", argv[i]) == 0)
{
......@@ -278,6 +286,11 @@ Init::Initialize(int &argc, char *argv[], int r, int n, bool strip, bool sigs)
strcpy(progname, progname2);
}
// if this is the engine and -vtk-debug is enabled, make sure the
// debuglevel is at least 1
if(vtk_debug && strstr(progname,"engine") != NULL && debuglevel < 1)
debuglevel = 1;
// Initialize the debug streams and also add the command line arguments
// to the debug logs.
DebugStream::Initialize(progname, debuglevel, sigs);
......
......@@ -61,6 +61,7 @@ const char *avtVariableCache::LABELS_NAME = "LABELS";
const char *avtVariableCache::ARRAYS_NAME = "ARRAYS";
const char *avtVariableCache::DATASET_NAME = "DATASET";
const char *avtVariableCache::DATA_SPECIFICATION = "DATA_SPECIFICATION";
bool avtVariableCache::vtkDebugMode = false;
// ****************************************************************************
// Method: avtVariableCache::DestructVTKObject
......@@ -185,6 +186,9 @@ avtCachableItem::~avtCachableItem()
// Hank Childs, Fri Oct 5 17:31:30 PDT 2001
// Added argument material.
//
// Cyrus Harrison, Sat Aug 11 19:28:13 PDT 2007
// Add call to DebugOn() for vtk-debug mode
//
// ****************************************************************************
vtkObject *
......@@ -202,6 +206,8 @@ avtVariableCache::GetVTKObject(const char *var, const char *type, int timestep,
if (item != NULL)
{
avtCachedVTKObject *vo = (avtCachedVTKObject *) item;
if(vtkDebugMode)
vo->GetVTKObject()->DebugOn();
return vo->GetVTKObject();
}
}
......
......@@ -101,6 +101,9 @@ class vtkObject;
// impl. single GetItem method for both classes (maybe should have
// implemented separately for each cacheable item type)
//
// Cyrus Harrison, Sat Aug 11 19:32:44 PDT 2007
// Add support for vtk-debug mode
//
// ****************************************************************************
class DATABASE_API avtVariableCache
......@@ -154,6 +157,8 @@ class DATABASE_API avtVariableCache
vtkObject *o2);
bool RemoveObjectPointerPair(vtkObject *o1);
vtkObject *FindObjectPointerPair(vtkObject *o1) const;
static void SetVTKDebugMode(bool on){vtkDebugMode = on;}
protected:
......@@ -241,6 +246,8 @@ class DATABASE_API avtVariableCache
std::vector<OneVar *> voidRefVars;
std::map<vtkObject*, vtkObject*> objectPointerMap;
static bool vtkDebugMode;
};
......
......@@ -447,7 +447,7 @@ CConvertUnstructuredGridToPolyData(avtDataRepresentation &data, void *, bool &)
//
// Arguments:
// data The data from which to calculate number of cells.
// <unused>
// arg optional bool pointer for enabling debug mode
// <unused>
//
// Notes:
......@@ -457,21 +457,46 @@ CConvertUnstructuredGridToPolyData(avtDataRepresentation &data, void *, bool &)
// Programmer: Hank Childs
// Creation: January 16, 2007
//
// Modifications:
//
// Cyrus Harrison, Sat Aug 11 19:44:59 PDT 2007
// Add support for vtk-debug mode.
//
// ****************************************************************************
void
CBreakVTKPipelineConnections(avtDataRepresentation &data, void *, bool &)
CBreakVTKPipelineConnections(avtDataRepresentation &data, void *arg, bool &)
{
if (!data.Valid())
{
return; // This is a problem, but no need to flag it for this...
}
// loop index
int i;
vtkDataSet *ds = data.GetDataVTK();
vtkDataSet *newDS = (vtkDataSet *) ds->NewInstance();
newDS->ShallowCopy(ds);
avtDataRepresentation new_data(newDS, data.GetDomain(),
data.GetLabel());
// If vtk-debug turn on debug for the new dataset and its vars
if(arg != NULL && *((bool*)arg))
{
newDS->DebugOn();
vtkCellData *cell_data = newDS->GetCellData();
vtkPointData *point_data = newDS->GetPointData();
int ncell_arrays = cell_data->GetNumberOfArrays();
for( i=0; i < ncell_arrays; i++)
cell_data->GetArray(i)->DebugOn();
int npoint_arrays = point_data->GetNumberOfArrays();
for( i=0; i < npoint_arrays; i++)
point_data->GetArray(i)->DebugOn();
}
data = new_data;
newDS->Delete();
}
......
......@@ -43,6 +43,7 @@
#include <avtCommonDataFunctions.h>
bool avtDataObjectToDatasetFilter::vtkDebugMode = false;
// ****************************************************************************
// Method: avtDataObjectToDatasetFilter constructor
......@@ -147,6 +148,9 @@ avtDataObjectToDatasetFilter::OutputSetActiveVariable(const char *varname)
// Hank Childs, Tue Jan 16 11:24:53 PST 2007
// Break all VTK pipeline connections.
//
// Cyrus Harrison, Sat Aug 11 19:48:30 PDT 2007
// Add support for vtk-debug mode.
//
// ****************************************************************************
void
......@@ -162,7 +166,7 @@ avtDataObjectToDatasetFilter::PostExecute(void)
tree->Traverse(CConvertUnstructuredGridToPolyData, NULL, dummy);
}
tree->Traverse(CBreakVTKPipelineConnections, NULL, dummy);
tree->Traverse(CBreakVTKPipelineConnections, (void*)&vtkDebugMode, dummy);
}
......@@ -68,6 +68,9 @@
// Convert unstructured data that could be stored as poly data to poly
// data.
//
// Cyrus Harrison, Sat Aug 11 19:53:13 PDT 2007
// Added support for vtk-debug mode.
//
// ****************************************************************************
class PIPELINE_API avtDataObjectToDatasetFilter
......@@ -80,6 +83,10 @@ class PIPELINE_API avtDataObjectToDatasetFilter
void OutputSetActiveVariable(const char *);
virtual void PostExecute(void);
static void SetVTKDebugMode(bool on){vtkDebugMode = on;}
private:
static bool vtkDebugMode;
};
......
......@@ -72,6 +72,7 @@
#include <SimulationCommand.h>
#include <SocketConnection.h>
#include <TimingsManager.h>
#include <vtkDebugStream.h>
#include <avtDatabaseMetaData.h>
#include <avtDataObjectReader.h>
......@@ -85,6 +86,8 @@
#include <avtTypes.h>
#include <avtVariableMapper.h>
#include <vtkDataSetWriter.h>
#include <avtDataObjectToDatasetFilter.h>
#include <avtVariableCache.h>
#include <string>
using std::string;
......@@ -1038,6 +1041,10 @@ Engine::ProcessInput()
//
// Mark C. Miller, Thu Jun 14 10:26:37 PDT 2007
// Added CL argument to specify cycle number regular expression
//
// Cyrus Harrison, Sat Aug 11 19:58:55 PDT 2007
// Added -vtk-debug option
//
// ****************************************************************************
void
......@@ -1168,6 +1175,12 @@ Engine::ProcessCommandLine(int argc, char **argv)
avtDataRepresentation::DatasetDump(false);
shouldDoDashDump = true;
}
else if (strcmp(argv[i], "-vtk-debug") == 0)
{
avtDataObjectToDatasetFilter::SetVTKDebugMode(true);
avtVariableCache::SetVTKDebugMode(true);
vtkDebugStream::FrequentEventsFilter(true);
}
else if (strcmp(argv[i], "-lb-block") == 0)
{
LoadBalancer::SetScheme(LOAD_BALANCE_CONTIGUOUS_BLOCKS_TOGETHER);
......
#!/usr/bin/env python
# ----------------------------------------------------------------------------
# Script that parses vtk messages from VisIt's engine debug logs and
# provides an xml report with possible vtk leaks.
# Usage example:
# (run visit with -vtk-debug to generate an engine debug log)
# vtk_debug_trace_parser.py engine_ser.1.log trace_output.xml
# firefox trace_output.xml
#
# ----------------------------------------------------------------------------
import sys
import os
class trace_set(object):
"A collection of trace objects"
def __init__(self,fname):
"Constructs a trace set"
self._parse_file_(fname)
def to_xml(self):
"Dumps trace set to xml string"
res = "<trace_set>\n"
for t in self.traces.values():
res += t.to_xml()
res += "</trace_set>\n"
return res
def size(self):
"Returns the number of trace objects"
return len(self.traces)
def _parse_file_(self,fname):
"Parses a visit debug for vtk events"
self.traces = {}
addy_reuse = {}
f = open(fname)
lines = f.readlines()
f.close()
for line in lines:
if self._valid_line_(line):
oaddy,otype,oevnt = self._parse_line_(line.strip())
if not self._check_filter_(oevnt):
# address reuse logic:
# checks # of times an address has rcved a
# Destructing! message, and increments a reuse
# counter. The unique key for an object is:
# address-reuse_number
# Example:
# 0x90d8300-0
if not oaddy in addy_reuse.keys():
addy_reuse[oaddy]=0;
oaddy_u = oaddy + "-%d" % addy_reuse[oaddy]
if not oaddy_u in self.traces.keys():
trace = trace_object(oaddy_u,otype)
self.traces[oaddy_u] = trace
self.traces[oaddy_u].add_event(oevnt)
if oevnt == "Destructing!":
addy_reuse[oaddy] += 1
return self.traces
def _valid_line_(self,txt):
"Checks if a line is a debug message we care about"
if txt[:3] == "vtk" and txt.find(" (") >0 and txt.find("):") >0:
return True
return False
def _parse_line_(self,txt):
"Extracts info from a debug message"
tok = txt.strip().split()
otype = tok[0]
oaddy = tok[1][1:-2]
oevnt = txt[txt.find(":")+1:].strip()
return oaddy,otype,oevnt
def _check_filter_(self,txt):
"Filters common messages"
if not txt.find("location = ") >=0:
return False
return True
class trace_object(object):
"Holds debug messages for a unique vtk object."
def __init__(self,oaddy,otype):
"Creates a trace object"
self.addy = oaddy
self.type = otype
self.ref_count = "unknown"
self.events = []
def check_event(self,txt):
"Checks if this object contains this event"
if txt in self.events:
return True
return False
def add_event(self,txt):
"Adds a new event"
self.events.append(txt)
rc_str ="ReferenceCount ="
rc_idx = txt.find(rc_str);
if rc_idx > 0:
rc = txt[rc_idx + len(rc_str)+1:]
self.ref_count = int(rc)
def __str__(self):
"Creates a human readable rep of this trace object"
res = "%s::%s\n" % ( self.addy , self.type )
for e in self.events:
res += " e:%s\n" % e
return res
def to_xml(self):
"Dumps trace object to xml string"
res = "<trace_object>\n"
res += " <addy>%s</addy>\n" % self.addy
res += " <type>%s</type>\n" % self.type
res += " <events>\n"
for e in self.events:
res += " <event>%s</event>\n" % e
res += " </events>\n"
res += "</trace_object>\n"
return res
class leak_set(object):
"Parses trace events to find non-destructed objects."
def __init__(self,trace_set):
"Constructs a leak set from a trace set"
self.leaks = {}
self.by_type = {}
for k,t in trace_set.traces.items():
if not t.check_event("Destructing!"):
if not t.type in self.by_type.keys():
self.by_type[t.type] =1;
else:
self.by_type[t.type] +=1;
self.leaks[k] = t
def to_xml(self):
"Dump leaks to xml string"
res = "<leak_set>\n"
for k,v in self.by_type.items():
res += "<type_summary><type>%s</type><count>%d</count></type_summary>\n" % (k,v)
for t in self.leaks.values():
res +=" <leak>\n "
res +=" <addy>%s</addy>\n " % t.addy
res +=" <type>%s</type>\n " % t.type
res +=" <ref_count>" + str(t.ref_count) + "</ref_count>\n "
res +=" </leak>\n"
res += "</leak_set>\n"
return res
def size(self):
"Return the # of leaks"
return len(self.leaks)
def output_header():
"Generates a valid xml output header with correct style sheet location"
style_file = os.path.dirname(os.path.abspath(sys.argv[0]))
style_file += "/vtk_debug_trace_style.xsl"
res = '<?xml version="1.0"?>\n'
res += '<?xml-stylesheet type="text/xsl" href="%s"?>\n' % style_file
res += '<root>\n'
return res;
def output_footer():
"Generates our xml output footer"
return '</root>\n'
def process(fname_in,fname_out):
"Creates trace and leak set and saves them as xml an output file"
#create a trace set
ts = trace_set(fname_in)
#create a leak set
ls = leak_set(ts)
# open output file, dump header and trace set
fout = open(fname_out,"w")
fout.write(output_header())
fout.write(ts.to_xml())
# if we have leaks dump these
if ls.size() >0:
fout.write(ls.to_xml())
# write footer
fout.write(output_footer())
fout.close()
def main():
if len(sys.argv) < 3:
print "usage: vtk_debug_trace_parser.py [engine_log] [output_file]"
sys.exit(-1)
engine_log = sys.argv[1]
output_file = sys.argv[2]
process(engine_log,output_file)
if __name__ == "__main__":
main()
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<html>
<header><title>VTK Trace Objects</title></header>
<body>
<xsl:for-each select="leak_set">
<h2>Leaks?</h2>
<table border="1">
<table cellspacing="5">
<xsl:for-each select="type_summary">
<tr><td><b>[<xsl:value-of select="type"/>]</b></td><td><xsl:value-of select="count"/></td></tr>
</xsl:for-each>
</table>
</table>
<br/>
<table border="1">
<table cellspacing="5">
<tr><td>Address:</td>
<td>Type:</td>
<td>Ref Count:</td>
</tr>
<xsl:for-each select="leak">
<tr><td><b>[<xsl:value-of select="addy"/>]</b></td>
<td><xsl:value-of select="type"/></td>
<td><xsl:value-of select="ref_count"/></td>
</tr>
</xsl:for-each>
</table>
</table>
</xsl:for-each>
<br/>
<h2>VTK Trace Objects</h2>
<xsl:for-each select="trace_set">
<xsl:for-each select="trace_object">
<table border="1">
<table>
<tr><td><b>[<xsl:value-of select="addy"/>]</b></td><td><xsl:value-of select="type"/></td></tr>
</table>
<table>
<tr><td><b>Events:</b></td></tr>
<xsl:for-each select="events/event">
<tr><td><xsl:value-of select="text()"/></td></tr>
</xsl:for-each>
</table>
</table>
<br/>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
......@@ -50,6 +50,12 @@
vtkStandardNewMacro(vtkDebugStream);
// *****************************************************
// Modifications:
// Cyrus Harrison, Sat Aug 11 20:37:23 PDT 2007
// Added init of filterFrequentEvents
// *****************************************************
bool vtkDebugStream::filterFrequentEvents = false;
// *****************************************************
// Modifications:
......@@ -64,8 +70,24 @@ void vtkDebugStream::Initialize(void)
ds->Delete();
}
// *****************************************************
// Modifications:
// Cyrus Harrison, Sat Aug 11 20:37:23 PDT 2007
// Added a filter for frequent events to reduce
// strain on file system.
// *****************************************************
void vtkDebugStream::DisplayText(const char *txt)
{
debug1 << txt << endl;
// exclude very frequent events to spare the fs
if(filterFrequentEvents)
{
bool ok = true;
ok = ok && strstr(txt,"Returning cell type") == NULL;
if(ok)
{debug1 << txt << endl;}
}
else
{debug1 << txt << endl;}
}
......@@ -51,6 +51,8 @@ public:
static void Initialize(void);
virtual void DisplayText(const char *);
static void FrequentEventsFilter(bool on){filterFrequentEvents = on;}
protected:
vtkDebugStream() {};
......@@ -59,6 +61,8 @@ protected:
private:
vtkDebugStream(const vtkDebugStream&);
void operator=(const vtkDebugStream&);
static bool filterFrequentEvents;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment