Commit 8ac5e307 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

BUG #14221. Avoid unnecessary gather with TextSourceRepresentation.

vtkTextSourceRepresentation was unnecessary doing a data-clone (despite the fact
that all data-server nodes have valid data). This added unnecessary
communication between all processes and hence was causing a performance
degradation as experienced by BUG #14221 (and other Catalyst users). Fixed that.
vtkTextSourceRepresentation still needs data delivered to client always (since
the 2D renderer is not composited), but we ensure that we no longer to any
gathers/scatters thus avoiding parallel communication.

Change-Id: I98a85ef4b911f813533ab7ed7c0ee4cee2adbca1
parent 92bcf920
......@@ -103,6 +103,8 @@ vtkMPIMoveData::vtkMPIMoveData()
this->UpdateNumberOfPieces = 0;
this->UpdatePiece = 0;
this->SkipDataServerGatherToZero = false;
}
//-----------------------------------------------------------------------------
......@@ -699,6 +701,14 @@ void vtkMPIMoveData::DataServerGatherToZero(vtkDataObject* input,
}
return;
}
if (this->SkipDataServerGatherToZero)
{
if (this->Controller->GetLocalProcessId() == 0 && input)
{
output->ShallowCopy(input);
}
return;
}
vtkTimerLog::MarkStartEvent("Dataserver gathering to 0");
......@@ -1210,6 +1220,8 @@ void vtkMPIMoveData::PrintSelf(ostream& os, vtkIndent indent)
os << indent << "NumberOfBuffers: " << this->NumberOfBuffers << endl;
os << indent << "Server: " << this->Server << endl;
os << indent << "MoveMode: " << this->MoveMode << endl;
os << indent << "SkipDataServerGatherToZero: " <<
this->SkipDataServerGatherToZero << endl;
os << indent << "OutputDataType: ";
if (this->OutputDataType == VTK_POLY_DATA)
{
......
......@@ -76,7 +76,8 @@ public:
void SetMoveModeToPassThrough(){this->MoveMode=vtkMPIMoveData::PASS_THROUGH;}
void SetMoveModeToCollect(){this->MoveMode=vtkMPIMoveData::COLLECT;}
void SetMoveModeToClone(){this->MoveMode=vtkMPIMoveData::CLONE;}
vtkSetClampMacro(MoveMode, int, vtkMPIMoveData::PASS_THROUGH, vtkMPIMoveData::CLONE);
vtkSetClampMacro(MoveMode, int, vtkMPIMoveData::PASS_THROUGH,
vtkMPIMoveData::COLLECT_AND_PASS_THROUGH);
// Description:
// Controls the output type. This is required because processes receiving
......@@ -102,6 +103,13 @@ public:
// successful Update() given the current ivars).
bool GetOutputGeneratedOnProcess();
// Description:
// When set, vtkMPIMoveData will skip the gather-to-root-node process
// altogether. This is useful when the data is already cloned on the
// server-nodes or we are interested in the root-node result alone.
vtkSetMacro(SkipDataServerGatherToZero, bool);
vtkGetMacro(SkipDataServerGatherToZero, bool);
//BTX
enum MoveModes {
PASS_THROUGH=0,
......@@ -155,6 +163,7 @@ protected:
int MoveMode;
int Server;
bool SkipDataServerGatherToZero;
//BTX
enum Servers {
CLIENT=0,
......
......@@ -99,7 +99,9 @@ public:
vtkOrderedCompositingInfo OrderedCompositingInfo;
vtkWeakPointer<vtkPVDataRepresentation> Representation;
bool AlwaysClone;
bool CloneDataToAllNodes;
bool DeliverToClientAndRenderingProcesses;
bool GatherBeforeDeliveringToClient;
bool Redistributable;
bool Streamable;
......@@ -107,7 +109,9 @@ public:
Producer(vtkSmartPointer<vtkPVTrivialProducer>::New()),
TimeStamp(0),
ActualMemorySize(0),
AlwaysClone(false),
CloneDataToAllNodes(false),
DeliverToClientAndRenderingProcesses(false),
GatherBeforeDeliveringToClient(false),
Redistributable(false),
Streamable(false)
{ }
......@@ -287,7 +291,24 @@ void vtkPVDataDeliveryManager::SetDeliverToAllProcesses(
vtkInternals::vtkItem* item = this->Internals->GetItem(repr, low_res);
if (item)
{
item->AlwaysClone = mode;
item->CloneDataToAllNodes = mode;
}
else
{
vtkErrorMacro("Invalid argument.");
}
}
//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::SetDeliverToClientAndRenderingProcesses(
vtkPVDataRepresentation* repr, bool deliver_to_client,
bool gather_before_delivery, bool low_res)
{
vtkInternals::vtkItem* item = this->Internals->GetItem(repr, low_res);
if (item)
{
item->DeliverToClientAndRenderingProcesses = deliver_to_client;
item->GatherBeforeDeliveringToClient = gather_before_delivery;
}
else
{
......@@ -484,10 +505,24 @@ void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned
dataMover->InitializeForCommunicationForParaView();
dataMover->SetOutputDataType(data->GetDataObjectType());
dataMover->SetMoveMode(mode);
if (item->AlwaysClone)
if (item->CloneDataToAllNodes)
{
dataMover->SetMoveModeToClone();
}
else if (item->DeliverToClientAndRenderingProcesses)
{
if (mode == vtkMPIMoveData::PASS_THROUGH)
{
dataMover->SetMoveMode(vtkMPIMoveData::COLLECT_AND_PASS_THROUGH);
}
else
{
// nothing to do, since the data is going to be delivered to the client
// anyways.
}
dataMover->SetSkipDataServerGatherToZero(
item->GatherBeforeDeliveringToClient == false);
}
dataMover->SetInputData(data);
if (dataMover->GetOutputGeneratedOnProcess())
......@@ -695,7 +730,7 @@ void vtkPVDataDeliveryManager::DeliverStreamedPieces(
dataMover->InitializeForCommunicationForParaView();
dataMover->SetOutputDataType(data->GetDataObjectType());
dataMover->SetMoveMode(mode);
if (item->AlwaysClone)
if (item->CloneDataToAllNodes)
{
dataMover->SetMoveModeToClone();
}
......
......@@ -85,6 +85,19 @@ public:
// this method (via vtkPVRenderView::SetDeliverToAllProcesses()).
void SetDeliverToAllProcesses(vtkPVDataRepresentation*, bool flag, bool low_res);
// Description:
// By default, this class only delivers geometries to nodes that are doing the
// rendering at a given stage. However, certain representations, such as
// text-source representation, need to the geometry to be delivered to the
// client as well. That can be done by using this method (via
// vtkPVRenderView::SetDeliverToAllProcesses()). The different between
// SetDeliverToAllProcesses() and this is that the former gather-and-scatters
// the data on the server nodes, while the latter will optionally gather the data to
// deliver to the client and never scatter.
void SetDeliverToClientAndRenderingProcesses(
vtkPVDataRepresentation*, bool deliver_to_client,
bool gather_before_delivery, bool low_res);
// Description:
// Under certain cases, e.g. when remote rendering in parallel with
// translucent geometry, the geometry may need to be redistributed to ensure
......
......@@ -1306,8 +1306,9 @@ void vtkPVRenderView::SetDeliverToAllProcesses(vtkInformation* info,
}
//----------------------------------------------------------------------------
void vtkPVRenderView::SetDeliverLODToAllProcesses(vtkInformation* info,
vtkPVDataRepresentation* repr, bool clone)
void vtkPVRenderView::SetDeliverToClientAndRenderingProcesses(
vtkInformation* info, vtkPVDataRepresentation* repr,
bool deliver_to_client, bool gather_before_delivery)
{
vtkPVRenderView* view = vtkPVRenderView::SafeDownCast(info->Get(VIEW()));
if (!view)
......@@ -1316,7 +1317,8 @@ void vtkPVRenderView::SetDeliverLODToAllProcesses(vtkInformation* info,
return;
}
view->GetDeliveryManager()->SetDeliverToAllProcesses(repr, clone, true);
view->GetDeliveryManager()->SetDeliverToClientAndRenderingProcesses(
repr, deliver_to_client, gather_before_delivery, false);
}
//----------------------------------------------------------------------------
......
......@@ -324,10 +324,6 @@ public:
vtkPVDataRepresentation* repr, vtkDataObject* data);
static vtkAlgorithmOutput* GetPieceProducerLOD(vtkInformation* info,
vtkPVDataRepresentation* repr);
static void SetDeliverToAllProcesses(
vtkInformation* info, vtkPVDataRepresentation* repr, bool clone);
static void SetDeliverLODToAllProcesses(
vtkInformation* info, vtkPVDataRepresentation* repr, bool clone);
static void MarkAsRedistributable(
vtkInformation* info, vtkPVDataRepresentation* repr);
static void SetGeometryBounds(vtkInformation* info,
......@@ -339,6 +335,25 @@ public:
static vtkDataObject* GetCurrentStreamedPiece(
vtkInformation* info, vtkPVDataRepresentation* repr);
// Description:
// Requests the view to deliver the pieces produced by the \c repr to all
// processes after a gather to the root node to merge the datasets generated
// by each process.
static void SetDeliverToAllProcesses(
vtkInformation* info, vtkPVDataRepresentation* repr, bool clone);
// Description:
// Requests the view to deliver the data to the client always. This is
// essential for representation that render in the non-composited views e.g.
// the text-source representation. If SetDeliverToAllProcesses() is true, this
// is redundant. \c gather_before_delivery can be used to indicate if the data
// on the server-nodes must be gathered to the root node before shipping to
// the client. If \c gather_before_delivery is false, only the data from the
// root node will be sent to the client without any parallel communication.
static void SetDeliverToClientAndRenderingProcesses(
vtkInformation* info, vtkPVDataRepresentation* repr,
bool deliver_to_client, bool gather_before_delivery);
// Description:
// Pass the structured-meta-data for determining rendering order for ordered
// compositing.
......
......@@ -167,7 +167,8 @@ int vtkTextSourceRepresentation::ProcessViewRequest(
{
vtkPVRenderView::SetPiece(inInfo, this,
this->CacheKeeper->GetOutputDataObject(0));
vtkPVRenderView::SetDeliverToAllProcesses(inInfo, this, true);
vtkPVRenderView::SetDeliverToClientAndRenderingProcesses(inInfo, this,
/*deliver_to_client=*/ true, /*gather_before_delivery=*/ false);
}
else if (request_type == vtkPVView::REQUEST_RENDER())
{
......
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