Commit f383ee5d authored by Utkarsh Ayachit's avatar Utkarsh Ayachit
Browse files

fix performance issues with field list.

Legacy API on vtkDataSetAttributesFieldList is potentially very slow.
Hence flagging it as deprecated and updating code that used the old API
to use a new `vtkDataSetAttributesFieldList::TransformData` method that
avoids the needs the for the legacy API.

Addresses paraview/paraview#18550.
parent f7e34a4c
......@@ -717,48 +717,85 @@ void vtkDataSetAttributesFieldList::InterpolatePoint(int inputIndex, vtkDataSetA
}
//----------------------------------------------------------------------------
void vtkDataSetAttributesFieldList::TransformData(int inputIndex, vtkDataSetAttributes* input,
vtkDataSetAttributes* output, std::function<void(vtkAbstractArray*, vtkAbstractArray*)> op) const
{
auto& internals = *this->Internals;
for (auto& pair : internals.Fields)
{
auto& fieldInfo = pair.second;
if (inputIndex < 0 || inputIndex > static_cast<int>(fieldInfo.Location.size()))
{
vtkGenericWarningMacro("Incorrect/unknown inputIndex specified : " << inputIndex);
return;
}
else if (fieldInfo.OutputLocation != -1 && fieldInfo.Location[inputIndex] != -1)
{
op(input->GetAbstractArray(fieldInfo.Location[inputIndex]),
output->GetAbstractArray(fieldInfo.OutputLocation));
}
}
}
//----------------------------------------------------------------------------
#if !defined(VTK_LEGACY_REMOVE)
int vtkDataSetAttributesFieldList::GetNumberOfFields() const
{
VTK_LEGACY_BODY(vtkDataSetAttributesFieldList::GetNumberOfFields, "VTK 8.2");
auto& internals = *this->Internals;
internals.Prune();
return vtkDataSetAttributes::NUM_ATTRIBUTES + static_cast<int>(internals.Fields.size());
}
#endif
//----------------------------------------------------------------------------
#if !defined(VTK_LEGACY_REMOVE)
int vtkDataSetAttributesFieldList::GetFieldIndex(int i) const
{
VTK_LEGACY_BODY(vtkDataSetAttributesFieldList::GetNumberOfFields, "VTK 8.2");
const auto& internals = *this->Internals;
const auto* finfo = internals.GetLegacyFieldForIndex(i);
return finfo ? finfo->OutputLocation : -1;
}
#endif
//----------------------------------------------------------------------------
#if !defined(VTK_LEGACY_REMOVE)
const char* vtkDataSetAttributesFieldList::GetFieldName(int i) const
{
VTK_LEGACY_BODY(vtkDataSetAttributesFieldList::GetNumberOfFields, "VTK 8.2");
const auto& internals = *this->Internals;
const auto* finfo = internals.GetLegacyFieldForIndex(i);
return finfo && finfo->Name.size() ? finfo->Name.c_str() : nullptr;
}
#endif
//----------------------------------------------------------------------------
#if !defined(VTK_LEGACY_REMOVE)
int vtkDataSetAttributesFieldList::GetDSAIndex(int index, int i) const
{
VTK_LEGACY_BODY(vtkDataSetAttributesFieldList::GetNumberOfFields, "VTK 8.2");
const auto& internals = *this->Internals;
const auto* finfo = internals.GetLegacyFieldForIndex(i);
return finfo && index >= 0 && index < static_cast<int>(finfo->Location.size())
? finfo->Location[index]
: -1;
}
#endif
//----------------------------------------------------------------------------
#if !defined(VTK_LEGACY_REMOVE)
int vtkDataSetAttributesFieldList::GetFieldComponents(int i) const
{
VTK_LEGACY_BODY(vtkDataSetAttributesFieldList::GetNumberOfFields, "VTK 8.2");
const auto& internals = *this->Internals;
const auto* finfo = internals.GetLegacyFieldForIndex(i);
return finfo ? finfo->NumberOfComponents : 0;
}
#endif
//----------------------------------------------------------------------------
#if !defined(VTK_LEGACY_REMOVE)
int vtkDataSetAttributesFieldList::IsAttributePresent(int attrType) const
{
const auto& internals = *this->Internals;
......@@ -769,6 +806,7 @@ int vtkDataSetAttributesFieldList::IsAttributePresent(int attrType) const
}
return 0;
}
#endif
//----------------------------------------------------------------------------
vtkSmartPointer<vtkAbstractArray> vtkDataSetAttributesFieldList::CreateArray(int type) const
......
......@@ -56,8 +56,11 @@
#define vtkDataSetAttributesFieldList_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkSystemIncludes.h"
#include "vtkSetGet.h" // for VTK_LEGACY
#include "vtkSmartPointer.h" // for vtkSmartPointer
#include "vtkSystemIncludes.h"
#include <functional> // for std::function
#include <memory> // for unique_ptr
class vtkAbstractArray;
......@@ -116,20 +119,29 @@ public:
double* weights, vtkDataSetAttributes* output, vtkIdType toId) const;
//@}
/**
* Use this method to provide a custom callback function to invoke for each
* array in the input and corresponding array in the output.
*/
void TransformData(int inputIndex, vtkDataSetAttributes* input, vtkDataSetAttributes* output,
std::function<void(vtkAbstractArray*, vtkAbstractArray*)> op) const;
//@{
/**
* vtkDataSetAttributes::FieldList used a different internal data structure in
* older versions of VTK. This exposes that API for legacy applications.
* It may be deprecated in the future.
*
* Using these methods should be avoided in new code.
* Using these methods should be avoided in new code and should be replaced in
* old code as these methods can be slow.
*
* @deprecated VTK 8.2
*/
int IsAttributePresent(int attrType) const;
int GetNumberOfFields() const;
int GetFieldIndex(int i) const;
const char* GetFieldName(int i) const;
int GetFieldComponents(int i) const;
int GetDSAIndex(int index, int i) const;
VTK_LEGACY(int IsAttributePresent(int attrType) const);
VTK_LEGACY(int GetNumberOfFields() const);
VTK_LEGACY(int GetFieldIndex(int i) const);
VTK_LEGACY(const char* GetFieldName(int i) const);
VTK_LEGACY(int GetFieldComponents(int i) const);
VTK_LEGACY(int GetDSAIndex(int index, int i) const);
//@}
protected:
......
......@@ -457,42 +457,36 @@ int vtkCellDataToPointData::RequestDataForUnstructuredData
cfl.InitializeFieldList(processedCellData);
opd->InterpolateAllocate(cfl, npoints, npoints);
for (int fid = 0, nfields = cfl.GetNumberOfFields(); fid < nfields; ++fid)
{
const auto nfields = processedCellData->GetNumberOfArrays();
int fid = 0;
auto f = [this, &fid, nfields, npoints, src, num, ncells, highestCellDimension](
vtkAbstractArray* aa_srcarray, vtkAbstractArray* aa_dstarray) {
// update progress and check for an abort request.
this->UpdateProgress((fid+1.)/nfields);
if (this->GetAbortExecute())
{
break;
}
this->UpdateProgress((fid + 1.0) / nfields);
++fid;
// indices into the field arrays associated with the cell and the point
// respectively
int const dstid = cfl.GetFieldIndex(fid);
int const srcid = cfl.GetDSAIndex(0,fid);
if (srcid < 0 || dstid < 0)
if (this->GetAbortExecute())
{
continue;
return;
}
vtkCellData * const srccelldata = processedCellData;
vtkPointData* const dstpointdata = dst->GetPointData();
if (!srccelldata || !dstpointdata)
vtkDataArray* const srcarray = vtkDataArray::FastDownCast(aa_srcarray);
vtkDataArray* const dstarray = vtkDataArray::FastDownCast(aa_dstarray);
if (srcarray && dstarray)
{
continue;
dstarray->SetNumberOfTuples(npoints);
vtkIdType const ncomps = srcarray->GetNumberOfComponents();
switch (srcarray->GetDataType())
{
vtkTemplateMacro(__spread<VTK_TT>(src, num, srcarray, dstarray, ncells, npoints, ncomps,
highestCellDimension, this->ContributingCellOption));
}
}
};
vtkDataArray* const srcarray = srccelldata ->GetArray(srcid);
vtkDataArray* const dstarray = dstpointdata->GetArray(dstid);
dstarray->SetNumberOfTuples(npoints);
vtkIdType const ncomps = srcarray->GetNumberOfComponents();
switch (srcarray->GetDataType())
{
vtkTemplateMacro
(__spread<VTK_TT>(src,num,srcarray,dstarray,ncells,npoints,ncomps, highestCellDimension, this->ContributingCellOption));
}
if (processedCellData != nullptr && dst->GetPointData() != nullptr)
{
cfl.TransformData(0, processedCellData, dst->GetPointData(), f);
}
if (!this->PassCellData)
......
......@@ -623,94 +623,77 @@ void vtkIntegrateAttributes::ZeroAttributes(vtkDataSetAttributes* outda)
void vtkIntegrateAttributes::IntegrateData1(vtkDataSetAttributes* inda, vtkDataSetAttributes* outda,
vtkIdType pt1Id, double k, vtkIntegrateAttributes::vtkFieldList& fieldList, int index)
{
int numArrays, i, numComponents, j;
vtkDataArray* inArray;
vtkDataArray* outArray;
numArrays = fieldList.GetNumberOfFields();
double vIn1, dv, vOut;
for (i = 0; i < numArrays; ++i)
{
if (fieldList.GetFieldIndex(i) < 0)
{
continue;
}
// We could template for speed.
inArray = inda->GetArray(fieldList.GetDSAIndex(index, i));
outArray = outda->GetArray(fieldList.GetFieldIndex(i));
numComponents = inArray->GetNumberOfComponents();
for (j = 0; j < numComponents; ++j)
auto f = [pt1Id, k](vtkAbstractArray* ainArray, vtkAbstractArray* aoutArray) {
vtkDataArray* inArray = vtkDataArray::FastDownCast(ainArray);
vtkDataArray* outArray = vtkDataArray::FastDownCast(aoutArray);
if (inArray && outArray)
{
vIn1 = inArray->GetComponent(pt1Id, j);
vOut = outArray->GetComponent(0, j);
dv = vIn1;
vOut += dv * k;
outArray->SetComponent(0, j, vOut);
// We could template for speed.
const int numComponents = inArray->GetNumberOfComponents();
for (int j = 0; j < numComponents; ++j)
{
const double vIn1 = inArray->GetComponent(pt1Id, j);
const double dv = vIn1;
const double vOut = (dv * k) + outArray->GetComponent(0, j);
outArray->SetComponent(0, j, vOut);
}
}
}
};
fieldList.TransformData(index, inda, outda, f);
}
//-----------------------------------------------------------------------------
void vtkIntegrateAttributes::IntegrateData2(vtkDataSetAttributes* inda, vtkDataSetAttributes* outda,
vtkIdType pt1Id, vtkIdType pt2Id, double k, vtkIntegrateAttributes::vtkFieldList& fieldList,
int index)
{
int numArrays, i, numComponents, j;
vtkDataArray* inArray;
vtkDataArray* outArray;
numArrays = fieldList.GetNumberOfFields();
double vIn1, vIn2, dv, vOut;
for (i = 0; i < numArrays; ++i)
{
if (fieldList.GetFieldIndex(i) < 0)
auto f = [pt1Id, pt2Id, k](vtkAbstractArray* ainArray, vtkAbstractArray* aoutArray) {
vtkDataArray* inArray = vtkDataArray::FastDownCast(ainArray);
vtkDataArray* outArray = vtkDataArray::FastDownCast(aoutArray);
if (inArray && outArray)
{
continue;
}
// We could template for speed.
inArray = inda->GetArray(fieldList.GetDSAIndex(index, i));
outArray = outda->GetArray(fieldList.GetFieldIndex(i));
numComponents = inArray->GetNumberOfComponents();
for (j = 0; j < numComponents; ++j)
{
vIn1 = inArray->GetComponent(pt1Id, j);
vIn2 = inArray->GetComponent(pt2Id, j);
vOut = outArray->GetComponent(0, j);
dv = 0.5 * (vIn1 + vIn2);
vOut += dv * k;
outArray->SetComponent(0, j, vOut);
// We could template for speed.
const int numComponents = inArray->GetNumberOfComponents();
for (int j = 0; j < numComponents; ++j)
{
const double vIn1 = inArray->GetComponent(pt1Id, j);
const double vIn2 = inArray->GetComponent(pt2Id, j);
const double dv = 0.5 * (vIn1 + vIn2);
const double vOut = (dv * k) + outArray->GetComponent(0, j);
outArray->SetComponent(0, j, vOut);
}
}
}
};
fieldList.TransformData(index, inda, outda, f);
}
//-----------------------------------------------------------------------------
// Is the extra performance worth duplicating this code with IntergrateData2.
void vtkIntegrateAttributes::IntegrateData3(vtkDataSetAttributes* inda, vtkDataSetAttributes* outda,
vtkIdType pt1Id, vtkIdType pt2Id, vtkIdType pt3Id, double k,
vtkIntegrateAttributes::vtkFieldList& fieldList, int index)
{
int numArrays, i, numComponents, j;
vtkDataArray* inArray;
vtkDataArray* outArray;
numArrays = fieldList.GetNumberOfFields();
double vIn1, vIn2, vIn3, dv, vOut;
for (i = 0; i < numArrays; ++i)
{
if (fieldList.GetFieldIndex(i) < 0)
auto f = [pt1Id, pt2Id, pt3Id, k](vtkAbstractArray* ainArray, vtkAbstractArray* aoutArray) {
vtkDataArray* inArray = vtkDataArray::FastDownCast(ainArray);
vtkDataArray* outArray = vtkDataArray::FastDownCast(aoutArray);
if (inArray && outArray)
{
continue;
}
// We could template for speed.
inArray = inda->GetArray(fieldList.GetDSAIndex(index, i));
outArray = outda->GetArray(fieldList.GetFieldIndex(i));
numComponents = inArray->GetNumberOfComponents();
for (j = 0; j < numComponents; ++j)
{
vIn1 = inArray->GetComponent(pt1Id, j);
vIn2 = inArray->GetComponent(pt2Id, j);
vIn3 = inArray->GetComponent(pt3Id, j);
vOut = outArray->GetComponent(0, j);
dv = (vIn1 + vIn2 + vIn3) / 3.0;
vOut += dv * k;
outArray->SetComponent(0, j, vOut);
// We could template for speed.
const int numComponents = inArray->GetNumberOfComponents();
for (int j = 0; j < numComponents; ++j)
{
const double vIn1 = inArray->GetComponent(pt1Id, j);
const double vIn2 = inArray->GetComponent(pt2Id, j);
const double vIn3 = inArray->GetComponent(pt3Id, j);
const double dv = (vIn1 + vIn2 + vIn3) / 3.0;
const double vOut = (dv * k) + outArray->GetComponent(0, j);
outArray->SetComponent(0, j, vOut);
}
}
}
};
fieldList.TransformData(index, inda, outda, f);
}
//-----------------------------------------------------------------------------
......@@ -719,33 +702,28 @@ void vtkIntegrateAttributes::IntegrateData4(vtkDataSetAttributes* inda, vtkDataS
vtkIdType pt1Id, vtkIdType pt2Id, vtkIdType pt3Id, vtkIdType pt4Id, double k,
vtkIntegrateAttributes::vtkFieldList& fieldList, int index)
{
int numArrays, i, numComponents, j;
vtkDataArray* inArray;
vtkDataArray* outArray;
numArrays = fieldList.GetNumberOfFields();
double vIn1, vIn2, vIn3, vIn4, dv, vOut;
for (i = 0; i < numArrays; ++i)
{
if (fieldList.GetFieldIndex(i) < 0)
auto f = [pt1Id, pt2Id, pt3Id, pt4Id, k](
vtkAbstractArray* ainArray, vtkAbstractArray* aoutArray) {
vtkDataArray* inArray = vtkDataArray::FastDownCast(ainArray);
vtkDataArray* outArray = vtkDataArray::FastDownCast(aoutArray);
if (inArray && outArray)
{
continue;
}
// We could template for speed.
inArray = inda->GetArray(fieldList.GetDSAIndex(index, i));
outArray = outda->GetArray(fieldList.GetFieldIndex(i));
numComponents = inArray->GetNumberOfComponents();
for (j = 0; j < numComponents; ++j)
{
vIn1 = inArray->GetComponent(pt1Id, j);
vIn2 = inArray->GetComponent(pt2Id, j);
vIn3 = inArray->GetComponent(pt3Id, j);
vIn4 = inArray->GetComponent(pt4Id, j);
vOut = outArray->GetComponent(0, j);
dv = (vIn1 + vIn2 + vIn3 + vIn4) * 0.25;
vOut += dv * k;
outArray->SetComponent(0, j, vOut);
// We could template for speed.
const int numComponents = inArray->GetNumberOfComponents();
for (int j = 0; j < numComponents; ++j)
{
const double vIn1 = inArray->GetComponent(pt1Id, j);
const double vIn2 = inArray->GetComponent(pt2Id, j);
const double vIn3 = inArray->GetComponent(pt3Id, j);
const double vIn4 = inArray->GetComponent(pt4Id, j);
const double dv = (vIn1 + vIn2 + vIn3 + vIn4) * 0.25;
const double vOut = (dv * k) + outArray->GetComponent(0, j);
outArray->SetComponent(0, j, vOut);
}
}
}
};
fieldList.TransformData(index, inda, outda, f);
}
//-----------------------------------------------------------------------------
......
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