Commit e410476d authored by hrchilds's avatar hrchilds

Update from March 28, 2005

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@439 18c085ea-50e0-402c-830e-de6fd14e8384
parent cabf6b91
......@@ -60,6 +60,9 @@ $0 = shift @ARGV;
# Hank Childs, Sun Mar 6 08:56:30 PST 2005
# Added -allowdynamic to fullhelp listing.
#
# Hank Childs, Mon Mar 28 10:00:15 PST 2005
# Added more timings options to -fullhelp.
#
###############################################################################
......@@ -225,6 +228,13 @@ $fullusage = "$usage
<level> must be between 1 and 5.
-pid Append process ids to the names of log files.
-timing Save timing data to files.
-withhold-timing-output
Withhold timing output during execution. Prevents
output of timing information from affecting
performance.
-timing-processor-stride N
Have only every Nth processor output timing info.
Prevents overwhelming parallel file systems.
-env Print env. variables VisIt will use when run.
-dump Dump intermediate results from AVT filters.
-gdb Run under gdb.
......
......@@ -27,8 +27,7 @@ int ftime(struct timeb *);
#endif
bool haveInitialized = false;
TimingsManager *visitTimer = TimingsManager::Initialize("default");
TimingsManager *visitTimer = NULL;
// ****************************************************************************
......@@ -114,6 +113,8 @@ TimingsManager::TimingsManager()
numTimings = 0;
numCurrentTimings = 0;
enabled = false;
withholdOutput = false;
outputAllTimings = false;
}
......@@ -140,13 +141,18 @@ TimingsManager::TimingsManager()
// Hank Childs, Tue Mar 22 16:13:20 PST 2005
// Fix memory leak.
//
// Hank Childs, Mon Mar 28 09:42:06 PST 2005
// Do not initialize the visit timer with a static constructor, because
// we don't know the name of the process yet.
//
// ****************************************************************************
TimingsManager *
TimingsManager::Initialize(const char *fname)
{
if (haveInitialized)
if (visitTimer != NULL)
return visitTimer;
#ifdef PARALLEL
visitTimer = new MPITimingsManager;
#else
......@@ -154,7 +160,6 @@ TimingsManager::Initialize(const char *fname)
#endif
visitTimer->SetFilename(fname);
haveInitialized = true;
return visitTimer;
}
......@@ -217,6 +222,46 @@ TimingsManager::Disable(void)
}
// ****************************************************************************
// Method: TimingsManager::WithholdOutput
//
// Purpose:
// Tells the timings manager not to output the timings until
// OutputAllTimings is called.
//
// Programmer: Hank Childs
// Creation: March 27, 2005
//
// ****************************************************************************
void
TimingsManager::WithholdOutput(bool v)
{
withholdOutput = v;
}
// ****************************************************************************
// Method: TimingsManager::OutputAllTimings
//
// Purpose:
// Tells the timings manager to truly output all the timings, even if
// we are withholding them.
//
// Programmer: Hank Childs
// Creation: March 27, 2005
//
// ****************************************************************************
void
TimingsManager::OutputAllTimings(void)
{
outputAllTimings = true;
DumpTimings();
outputAllTimings = false;
}
// ****************************************************************************
// Method: TimingsManager::StartTimer
//
......@@ -325,6 +370,9 @@ TimingsManager::StopTimer(int index, const std::string &summary)
// Eric Brugger, Mon Nov 5 14:17:24 PST 2001
// I added the ability to enable and disable timings.
//
// Hank Childs, Sun Mar 27 13:38:03 PST 2005
// Do not output if we are withholding timings.
//
// ****************************************************************************
void
......@@ -337,6 +385,8 @@ TimingsManager::DumpTimings(void)
{
return;
}
if (withholdOutput && !outputAllTimings)
return;
ofstream ofile;
......@@ -383,6 +433,9 @@ TimingsManager::DumpTimings(void)
// Eric Brugger, Mon Nov 5 14:17:24 PST 2001
// I added the ability to enable and disable timings.
//
// Hank Childs, Sun Mar 27 13:38:03 PST 2005
// Do not output if we are withholding timings.
//
// ****************************************************************************
void
......@@ -395,6 +448,8 @@ TimingsManager::DumpTimings(ostream &out)
{
return;
}
if (withholdOutput && !outputAllTimings)
return;
int numT = times.size();
for (int i = 0 ; i < numT ; i++)
......
......@@ -82,12 +82,17 @@ class MISC_API TimingsManager
void DumpTimings(void);
void DumpTimings(ostream &);
void WithholdOutput(bool);
void OutputAllTimings();
protected:
std::string filename;
bool openedFile;
int numCurrentTimings;
int numTimings;
bool enabled;
bool withholdOutput;
bool outputAllTimings;
std::vector<double> times;
std::vector<std::string> summaries;
......
......@@ -361,6 +361,9 @@ avtGenericDatabase::SetDatabaseMetaData(avtDatabaseMetaData *md, int timeState)
// Hank Childs, Sat Mar 5 19:26:05 PST 2005
// Do not do collective communication if we are in DLB mode.
//
// Hank Childs, Mon Mar 28 15:14:39 PST 2005
// Add some more timing information.
//
// ****************************************************************************
avtDataTree_p
......@@ -441,7 +444,8 @@ avtGenericDatabase::GetOutput(avtDataSpecification_p spec,
// way to handle this.
//
hadError = true;
debug1 << "Catching the exception at the generic database level." << endl;
debug1 << "Catching the exception at the generic database level."
<< endl;
avtDataValidity &v = src->GetOutput()->GetInfo().GetValidity();
v.ErrorOccurred();
string tmp = e.Message(); // Otherwise there is a const problem.
......@@ -452,6 +456,7 @@ avtGenericDatabase::GetOutput(avtDataSpecification_p spec,
avtDataValidity &validity = src->GetOutput()->GetInfo().GetValidity();
bool canDoCollectiveCommunication = !validity.GetIsThisDynamic();
#ifdef PARALLEL
int t1 = visitTimer->StartTimer();
if (canDoCollectiveCommunication)
{
//
......@@ -465,6 +470,7 @@ avtGenericDatabase::GetOutput(avtDataSpecification_p spec,
shouldDoMatSelect = bool(rtmp[0]);
hadError = bool(rtmp[1]);
}
visitTimer->StopTimer(t1, "Waiting for all processors to catch up");
#endif
if (hadError)
......
......@@ -2432,6 +2432,10 @@ avtRectilinearDomainBoundaries::ExchangeMesh(vector<int> domainNum,
// Hank Childs, Sun Feb 27 14:47:45 PST 2005
// Added argument allDomains.
//
// Hank Childs, Mon Mar 28 13:38:14 PST 2005
// Do not create domain-processor map, since that requires communication
// and cannot be used with dynamic load balancing.
//
// ****************************************************************************
void
......@@ -2439,8 +2443,6 @@ avtStructuredDomainBoundaries::CreateGhostNodes(vector<int> domainNum,
vector<vtkDataSet*> meshes,
vector<int> &allDomains)
{
vector<int> domain2proc = CreateDomainToProcessorMap(domainNum);
//
// If we are doing DLB, we want to mark nodes as ghost, even if their
// neighboring domains are not being used on this iteration. Do this by
......@@ -2448,6 +2450,8 @@ avtStructuredDomainBoundaries::CreateGhostNodes(vector<int> domainNum,
// trick because the rest of the routine does not care which domains
// are on which processors -- only that we are using them.
//
int ntotaldomains = wholeBoundary.size();
vector<int> domain2proc(ntotaldomains, -1);
for (int i = 0 ; i < allDomains.size() ; i++)
{
if (domain2proc[allDomains[i]] < 0)
......
......@@ -56,6 +56,9 @@
# Hank Childs, Sun Mar 13 10:11:07 PST 2005
# Added avtStructuredMeshChunker.
#
# Hank Childs, Sun Mar 27 11:22:06 PST 2005
# Moved avtStructuredMeshChunker to Pipeline/PrivateFilters.
#
##############################################################################
##
......@@ -92,11 +95,8 @@ SRC=\
avtShiftCenteringFilter.C \
avtSimilarityTransformFilter.C \
avtSmoothPolyDataFilter.C \
avtStructuredMeshChunker.C \
avtStructuredMeshPartitionStrategy.C \
avtSummationFilter.C \
avtSurfaceFilter.C \
avtSweepPlanePartitionStrategy.C \
avtTiledImageCompositor.C \
avtTransform.C \
avtVertexNormalsFilter.C \
......
......@@ -299,6 +299,10 @@ PrivateFilters_src= \
PrivateFilters/avtSamplePointsToSamplePointsFilter.C \
PrivateFilters/avtSingleFilterFacade.C \
PrivateFilters/avtStreamer.C \
PrivateFilters/avtStructuredChunkStreamer.C \
PrivateFilters/avtStructuredMeshChunker.C \
PrivateFilters/avtStructuredMeshPartitionStrategy.C \
PrivateFilters/avtSweepPlanePartitionStrategy.C \
PrivateFilters/avtTimeLoopFilter.C
Sinks_src= \
......
// ************************************************************************* //
// avtPluginStructuredChunkStreamer.h //
// ************************************************************************* //
#ifndef AVT_PLUGIN_STRUCTURED_CHUNK_STREAMER_H
#define AVT_PLUGIN_STRUCTURED_CHUNK_STREAMER_H
#include <pipeline_exports.h>
#include <avtStructuredChunkStreamer.h>
#include <avtPluginFilter.h>
// ****************************************************************************
// Class: avtPluginStructuredChunkStreamer
//
// Purpose:
// A base class for plugin-style operators that are
// avtStructuredChunkStreamers.
//
// Programmer: Hank Childs
// Creation: March 27, 2005
//
// ****************************************************************************
class PIPELINE_API avtPluginStructuredChunkStreamer :
public virtual avtStructuredChunkStreamer,
public virtual avtPluginFilter
{
};
#endif
// ************************************************************************* //
// avtStructuredChunkStreamer.C //
// ************************************************************************* //
#include <avtStructuredChunkStreamer.h>
#include <vtkRectilinearGrid.h>
#include <vtkStructuredGrid.h>
#include <vtkUnstructuredGrid.h>
// ****************************************************************************
// Method: avtStructuredChunkStreamer constructor
//
// Programmer: Hank Childs
// Creation: April 27, 2005
//
// ****************************************************************************
avtStructuredChunkStreamer::avtStructuredChunkStreamer()
{
downstreamRectilinearMeshOptimizations = false;
downstreamCurvilinearMeshOptimizations = false;
downstreamGhostType = NO_GHOST_DATA;
chunkedStructuredMeshes = false;
}
// ****************************************************************************
// Method: avtStructuredChunkStreamer destructor
//
// Programmer: Hank Childs
// Creation: April 27, 2005
//
// ****************************************************************************
avtStructuredChunkStreamer::~avtStructuredChunkStreamer()
{
}
// ****************************************************************************
// Method: avtStructuredChunkStreamer::ExecuteDataTree
//
// Programmer: Hank Childs
// Creation: April 27, 2005
//
// ****************************************************************************
avtDataTree_p
avtStructuredChunkStreamer::ExecuteDataTree(vtkDataSet *in_ds, int domain,
std::string label)
{
int ds_type = in_ds->GetDataObjectType();
bool haveStructured = (ds_type == VTK_RECTILINEAR_GRID ||
ds_type == VTK_STRUCTURED_GRID);
bool downstreamOptimizations = false;
int dims[3] = { 0, 0, 0 };
if (ds_type == VTK_RECTILINEAR_GRID)
{
vtkRectilinearGrid *rgrid = (vtkRectilinearGrid *) in_ds;
rgrid->GetDimensions(dims);
downstreamOptimizations = downstreamRectilinearMeshOptimizations;
}
else if (ds_type == VTK_STRUCTURED_GRID)
{
vtkStructuredGrid *sgrid = (vtkStructuredGrid *) in_ds;
sgrid->GetDimensions(dims);
downstreamOptimizations = downstreamCurvilinearMeshOptimizations;
}
//bool canChunk = haveStructured;
bool canChunk = false; // Turn off for now.
if (dims[0] <= 1 || dims[1] <= 1 || dims[2] <= 1)
canChunk = false;
if (!canChunk)
{
vtkDataSet *out = ProcessOneChunk(in_ds, domain, label, false);
avtDataTree_p rv = new avtDataTree(1, &out, domain, label);
if (out != NULL)
out->Delete();
return rv;
}
int ncells = in_ds->GetNumberOfCells();
vector<avtStructuredMeshChunker::ZoneDesignation> designation(ncells);
// cell-dims
dims[0] -= 1;
dims[1] -= 1;
dims[2] -= 1;
GetAssignments(in_ds, dims, designation);
vtkUnstructuredGrid *ugrid = NULL;
vector<vtkDataSet *> grids;
avtStructuredMeshChunker::ChunkStructuredMesh(in_ds, designation,
grids, ugrid, downstreamGhostType, downstreamOptimizations);
vtkDataSet *out_ugrid = ProcessOneChunk(ugrid, domain, label, true);
//
// Create a data tree that has all of the structured meshes, as well
// as the single unstructured mesh.
//
vtkDataSet **out_ds = new vtkDataSet*[grids.size()+1];
for (int i = 0 ; i < grids.size() ; i++)
out_ds[i] = grids[i];
out_ds[grids.size()] = out_ugrid;
avtDataTree_p rv = new avtDataTree(grids.size()+1, out_ds, domain, label);
delete [] out_ds;
if (out_ugrid != NULL)
out_ugrid->Delete();
if (ugrid != NULL)
ugrid->Delete();
chunkedStructuredMeshes = true;
return rv;
}
// ****************************************************************************
// Method: avtStructuredChunkStreamer::PerformRestriction
//
// Purpose:
// Inspect the input specification and determine what its requirements
// are.
//
// Programmer: Hank Childs
// Creation: March 27, 2005
//
// ****************************************************************************
avtPipelineSpecification_p
avtStructuredChunkStreamer::PerformRestriction(avtPipelineSpecification_p spec)
{
downstreamRectilinearMeshOptimizations =
spec->GetHaveRectilinearMeshOptimizations();
downstreamCurvilinearMeshOptimizations =
spec->GetHaveCurvilinearMeshOptimizations();
downstreamGhostType =
spec->GetDataSpecification()->GetDesiredGhostDataType();
return spec;
}
// ****************************************************************************
// Method: avtStructuredChunkStreamer::PreExecute
//
// Purpose:
// Initialize chunkedStructuredMesh.
//
// Programmer: Hank Childs
// Creation: March 27, 2005
//
// ****************************************************************************
void
avtStructuredChunkStreamer::PreExecute(void)
{
avtDataTreeStreamer::PreExecute();
chunkedStructuredMeshes = false;
}
// ****************************************************************************
// Method: avtStructuredChunkStreamer::PostExecute
//
// Purpose:
// If we chunked a structured mesh, indicate that we may now have ghost
// data.
//
// Programmer: Hank Childs
// Creation: March 27, 2005
//
// ****************************************************************************
void
avtStructuredChunkStreamer::PostExecute(void)
{
avtDataTreeStreamer::PostExecute();
if (chunkedStructuredMeshes && downstreamGhostType != NO_GHOST_DATA)
{
GetOutput()->GetInfo().GetAttributes().
SetContainsGhostZones(AVT_CREATED_GHOSTS);
}
}
// ************************************************************************* //
// avtStructuredChunkStreamer.h //
// ************************************************************************* //
#ifndef AVT_STRUCTURED_CHUNK_STREAMER_H
#define AVT_STRUCTURED_CHUNK_STREAMER_H
#include <pipeline_exports.h>
#include <avtDataTreeStreamer.h>
#include <avtGhostData.h>
#include <avtStructuredMeshChunker.h>
// ****************************************************************************
// Class: avtStructuredChunkStreamer
//
// Purpose:
// This is an abstract type that prepares a filter to interact with
// the structured mesh chunker module. It is possible to use the
// structured mesh chunker without the help of this class -- it's sole
// purpose is to do bookkeeping to ease the burden for derived types,
// as well as remove redundant code.
//
// Programmer: Hank Childs
// Creation: March 27, 2005
//
// ****************************************************************************
class PIPELINE_API avtStructuredChunkStreamer : public avtDataTreeStreamer
{
public:
avtStructuredChunkStreamer();
virtual ~avtStructuredChunkStreamer();
protected:
bool downstreamRectilinearMeshOptimizations;
bool downstreamCurvilinearMeshOptimizations;
avtGhostDataType downstreamGhostType;
bool chunkedStructuredMeshes;
virtual avtDataTree_p ExecuteDataTree(vtkDataSet *,int,std::string);
virtual vtkDataSet *ProcessOneChunk(vtkDataSet *,int,std::string,
bool) = 0;
virtual void GetAssignments(vtkDataSet *, const int *,
std::vector<avtStructuredMeshChunker::ZoneDesignation>&)=0;
virtual avtPipelineSpecification_p
PerformRestriction(avtPipelineSpecification_p);
virtual void PreExecute(void);
virtual void PostExecute(void);
};
#endif
......@@ -36,6 +36,7 @@
#include <avtDataset.h>
#include <avtFilter.h>
#include <avtOriginatingSink.h>
#include <avtParallel.h>
#include <avtStreamer.h>
#include <avtTerminatingSource.h>
#include <avtVariableMapper.h>
......@@ -46,7 +47,6 @@ using std::string;
#ifdef PARALLEL
#include <parallel.h>
#include <avtParallel.h>
#else
#include <Xfer.h>
#endif
......@@ -828,17 +828,50 @@ Engine::ProcessInput()
// Hank Childs, Sun Mar 6 08:42:50 PST 2005
// Renamed -forcedynamic to -allowdynamic. Removed -forcestatic argument.
//
// Hank Childs, Sun Mar 27 13:29:13 PST 2005
// Added more timing arguments.
//
// ****************************************************************************
void
Engine::ProcessCommandLine(int argc, char **argv)
{
// process arguments.
bool timingsAllowed = true;
for (int i=1; i<argc; i++)
{
if (strcmp(argv[i], "-allowdynamic") == 0)
LoadBalancer::AllowDynamic();
else if (strcmp(argv[i], "-timing") == 0)
else if ((strcmp(argv[i], "-timing") == 0) && timingsAllowed)
visitTimer->Enable();
else if (strcmp(argv[i], "-timing-processor-stride") == 0)
{
int stride = 1;
if (i+1 < argc)
{
i++;
stride = atoi(argv[i]);
}
if (stride <= 0)
{
if (PAR_Rank() != 0)
{
visitTimer->Disable();
timingsAllowed = false;
}
}
else
{
int modulo = (PAR_Rank() % stride);
if (modulo != 0)
{
visitTimer->Disable();
timingsAllowed = false;
}
}
}
else if (strcmp(argv[i], "-withhold-timing-output") == 0)
visitTimer->WithholdOutput(true);
else if (strcmp(argv[i], "-timeout") == 0)
{
timeout = atol(argv[i+1]);
......
......@@ -822,6 +822,10 @@ RPCExecutor<SetWinAnnotAttsRPC>::Execute(SetWinAnnotAttsRPC *rpc)
//
// Mark C. Miller, Tue Jan 4 10:23:19 PST 2005
// Added code to operate on specific window id
//
// Hank Childs, Sun Mar 27 14:02:22 PST 2005
// Use OutputAllTimings, in case timings are being withheld.
//
// ****************************************************************************
template<>
void
......@@ -930,7 +934,7 @@ RPCExecutor<ExecuteRPC>::Execute(ExecuteRPC *rpc)
{
visitTimer->StopTimer(writingData, "Writing data to viewer");
}
visitTimer->DumpTimings();
visitTimer->OutputAllTimings();
}
// ****************************************************************************
......
......@@ -177,7 +177,7 @@ avtClipFilter::Equivalent(const AttributeGroup *a)
// ****************************************************************************
// Method: avtClipFilter::ExecuteData
// Method: avtClipFilter::ProcessOneChunk
//
// Purpose:
// Sends the specified input and output through the Clip filter.
......@@ -186,6 +186,8 @@ avtClipFilter::Equivalent(const AttributeGroup *a)
// in_ds The input dataset.
// dom The domain number.
// label The label.
// isChunked Whether or not the data set is produced by the structured
// mesh chunker -- not important for this module.
//
// Returns: The output unstructured grid.
//
......@@ -200,10 +202,14 @@ avtClipFilter::Equivalent(const AttributeGroup *a)
// Hank Childs, Thu Mar 10 14:33:32 PST 2005
// Instantiate filters on the fly.
//
// Hank Childs, Sun Mar 27 12:00:18 PST 2005
// Renamed to ProcessOneChunk. Changed memory management. Fix small
// memory leak in error condition.
//
// ****************************************************************************
vtkDataSet *
avtClipFilter::ExecuteData(vtkDataSet *inDS, int dom, std::string)
avtClipFilter::ProcessOneChunk(vtkDataSet *inDS, int dom, std::string, bool)
{
vtkClipPolyData *clipPoly = vtkClipPolyData::New();
vtkVisItClipper *fastClipper = vtkVisItClipper::New();
......@@ -214,6 +220,9 @@ avtClipFilter::ExecuteData(vtkDataSet *inDS, int dom, std::string)
if (!funcSet)