From ba13c9d56bf9ad5e5312cc30066bdcf43d1b324a Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Mon, 24 Oct 2022 09:10:44 +0200 Subject: [PATCH] Get rid off deepCopy in // mode and limitation of number of requestInformation --- .../MEDReaderIO/vtkFileSeriesGroupReader.cxx | 92 ++++++++++++------- .../plugin/MEDReaderIO/vtkMEDReader.cxx | 6 +- .../plugin/MEDReaderIO/vtkMEDReader.h | 28 +++++- 3 files changed, 87 insertions(+), 39 deletions(-) diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkFileSeriesGroupReader.cxx b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkFileSeriesGroupReader.cxx index 31d4702a..28f64fcd 100644 --- a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkFileSeriesGroupReader.cxx +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkFileSeriesGroupReader.cxx @@ -19,6 +19,7 @@ #include "vtkFileSeriesGroupReader.h" +#include #include #include #include @@ -38,6 +39,7 @@ vtkStandardNewMacro(vtkFileSeriesGroupReader); struct vtkFileSeriesGroupReaderInternals { std::vector FileNames; + vtkNew ReaderCollection; }; //============================================================================= @@ -129,21 +131,36 @@ int vtkFileSeriesGroupReader::RequestData(vtkInformation* vtkNotUsed(request), unsigned int iProc = vmpc ? vmpc->GetLocalProcessId() : 0; unsigned int nProc = vmpc ? vmpc->GetNumberOfProcesses() : 1; - // Simple case, one file/block per proc - if (nBlock == 1 || (nBlock <= nProc && iProc < nBlock)) + // Simple case, one file/bloc for n proc + if (nBlock == 1) { - // Distribute in MEDReader only when reading a single file in a single block - iProc = nBlock == 1 ? 0 : iProc; - vtkMEDReader::SafeDownCast(this->Reader)->SetDistributeWithMPI(nBlock == 1); + // Make sure the information is up to date + this->ReaderSetFileName(this->GetFileName(0)); + vtkMEDReader::SafeDownCast(this->Reader)->ReloadInternals(); + this->Reader->UpdateInformation(); - this->ReaderSetFileName(this->GetFileName(iProc)); + this->Reader->UpdateTimeStep(time); + vtkDataObject* outputReader = vtkMultiBlockDataSet::SafeDownCast(this->Reader->GetOutputDataObject(0))->GetBlock(0); + output->SetBlock(0, outputReader); - // Needed only when reading a different file on each proc - if (nBlock != 1) + // Copy the GAUSS_DATA info key + vtkInformation* mInfo = this->Reader->GetOutputInformation(0); + if (mInfo->Has(vtkMEDReader::GAUSS_DATA())) { - vtkMEDReader::SafeDownCast(this->Reader)->ReloadInternals(); - this->Reader->UpdateInformation(); + info->CopyEntry(mInfo, vtkMEDReader::GAUSS_DATA()); } + } + // N file/block read by m proc, with n <= m, means 0/1 file/block per proc + else if (nBlock <= nProc && iProc < nBlock) + { + // Distribute in MEDReader only when reading a single file in a single block + vtkMEDReader::SafeDownCast(this->Reader)->SetDistributeWithMPI(false); + + // Needed as the MEDReader do not support changing its filename + // without reloading everything. + this->ReaderSetFileName(this->GetFileName(iProc)); + vtkMEDReader::SafeDownCast(this->Reader)->ReloadInternals(); + this->Reader->UpdateInformation(); this->Reader->UpdateTimeStep(time); vtkDataObject* outputReader = vtkMultiBlockDataSet::SafeDownCast(this->Reader->GetOutputDataObject(0))->GetBlock(0); @@ -156,9 +173,9 @@ int vtkFileSeriesGroupReader::RequestData(vtkInformation* vtkNotUsed(request), info->CopyEntry(mInfo, vtkMEDReader::GAUSS_DATA()); } } + // Multiple files/block per proc else { - // Multiple files/block per proc unsigned int nFiles = nBlock / nProc; unsigned int offFile = iProc * nFiles; unsigned int supFiles = nBlock % nProc; @@ -169,33 +186,46 @@ int vtkFileSeriesGroupReader::RequestData(vtkInformation* vtkNotUsed(request), nFiles += supFiles; } + vtkMEDReader* exposedReader = vtkMEDReader::SafeDownCast(this->Reader); + this->Internals->ReaderCollection->RemoveAllItems(); for (unsigned int i = 0; i < nFiles; i++) { - this->ReaderSetFileName(this->GetFileName(i + offFile)); - vtkMEDReader::SafeDownCast(this->Reader)->SetDistributeWithMPI(false); - vtkMEDReader::SafeDownCast(this->Reader)->ReloadInternals(); - this->Reader->UpdateInformation(); - this->Reader->UpdateTimeStep(time); - vtkDataObject* outputReader = vtkMultiBlockDataSet::SafeDownCast(this->Reader->GetOutputDataObject(0))->GetBlock(0); - if (i + 1 == nFiles) + // Create as many MEDReader as we need to avoid deep copy + vtkNew localReader; + this->Internals->ReaderCollection->AddItem(localReader.Get()); + + for (int iField = 0; iField < exposedReader->GetNumberOfFieldsTreeArrays(); iField++) { - // Last reader, just use the reader output directly - output->SetBlock(i + offFile, outputReader); + const char* name = exposedReader->GetFieldsTreeArrayName(iField); + localReader->SetFieldsStatus(name, exposedReader->GetFieldsTreeArrayStatus(name)); } - else + for (int iTimes = 0; iTimes < exposedReader->GetNumberOfTimesFlagsArrays(); iTimes++) { - // Need to deep copy as the reader will be reused - vtkSmartPointer outputLeaf = vtkSmartPointer::Take(outputReader->NewInstance()); - outputLeaf->DeepCopy(outputReader); - output->SetBlock(i + offFile, outputLeaf); + const char* name = exposedReader->GetTimesFlagsArrayName(iTimes); + localReader->SetTimesFlagsStatus(name, exposedReader->GetTimesFlagsArrayStatus(name)); } - } + localReader->GenerateVectors(exposedReader->GetGenerateVect()); + localReader->ChangeMode(exposedReader->GetIsStdOrMode()); + localReader->GhostCellGeneratorCallForPara(exposedReader->GetGCGCP()); - // Copy the GAUSS_DATA info key for the last reader - vtkInformation* mInfo = this->Reader->GetOutputInformation(0); - if (mInfo->Has(vtkMEDReader::GAUSS_DATA())) - { - info->CopyEntry(mInfo, vtkMEDReader::GAUSS_DATA()); + // Configure the localReader for usage with the files + localReader->SetFileName(this->GetFileName(i + offFile)); + localReader->SetDistributeWithMPI(false); + localReader->UpdateInformation(); + localReader->UpdateTimeStep(time); + + vtkDataObject* outputReader = vtkMultiBlockDataSet::SafeDownCast(localReader->GetOutputDataObject(0))->GetBlock(0); + output->SetBlock(i + offFile, outputReader); + + if (i == 0) + { + // Copy the GAUSS_DATA info key of the first filename + vtkInformation* mInfo = localReader->GetOutputInformation(0); + if (mInfo->Has(vtkMEDReader::GAUSS_DATA())) + { + info->CopyEntry(mInfo, vtkMEDReader::GAUSS_DATA()); + } + } } } return 1; diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.cxx b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.cxx index ea9ce437..7737fcbb 100755 --- a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.cxx +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.cxx @@ -104,12 +104,12 @@ vtkInformationDataObjectMetaDataKey *vtkMEDReader::META_DATA() return ret; } -static vtkInformationDoubleVectorKey *vtkMEDReader_GAUSS_DATA=new vtkInformationDoubleVectorKey("GAUSS_DATA","vtkFileSeriesGroupReader"); +static vtkInformationGaussDoubleVectorKey *vtkMEDReader_GAUSS_DATA=new vtkInformationGaussDoubleVectorKey("GAUSS_DATA","vtkFileSeriesGroupReader"); -vtkInformationDoubleVectorKey *vtkMEDReader::GAUSS_DATA() +vtkInformationGaussDoubleVectorKey *vtkMEDReader::GAUSS_DATA() { static const char ZE_KEY[]="vtkFileSeriesGroupReader::GAUSS_DATA"; - vtkInformationDoubleVectorKey *ret(vtkMEDReader_GAUSS_DATA); + vtkInformationGaussDoubleVectorKey *ret(vtkMEDReader_GAUSS_DATA); MEDCoupling::GlobalDict *gd(MEDCoupling::GlobalDict::GetInstance()); if(!gd->hasKey(ZE_KEY)) {// here META_DATA is put on global var to be exchanged with other filters without dependancy of MEDReader. Please do not change ZE_KEY ! diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.h b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.h index fcf4cc29..03b1cb47 100755 --- a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.h +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.h @@ -24,13 +24,14 @@ #include #include "vtkMultiBlockDataSetAlgorithm.h" -#include "vtkInformationDoubleVectorKey.h" +#include "vtkInformationGaussDoubleVectorKey.h" #include "vtkNew.h" class vtkDataArraySelection; class vtkDataSet; class vtkMutableDirectedGraph; class vtkInformationDataObjectMetaDataKey; +class vtkInformationDoubleVectorKey; class ExportedTinyInfo; class VTK_EXPORT vtkMEDReader : public vtkMultiBlockDataSetAlgorithm @@ -68,22 +69,39 @@ class VTK_EXPORT vtkMEDReader : public vtkMultiBlockDataSetAlgorithm // ReloadInternals will delete the internal reader and recreate it virtual void ReloadInternals(); - virtual void GenerateVectors(int); - virtual void ChangeMode(int); - virtual void GhostCellGeneratorCallForPara(int); static const char *GetSeparator(); // Description // Static information key used to transfer the meta data graph along the pipeline static vtkInformationDataObjectMetaDataKey* META_DATA(); - static vtkInformationDoubleVectorKey* GAUSS_DATA(); + static vtkInformationGaussDoubleVectorKey* GAUSS_DATA(); // Description // Control if MPI should be used for distribution when using a distributed server // Only has an effect if MEDREADER_USE_MPI is defined. + // Default is true vtkSetMacro(DistributeWithMPI, bool); vtkGetMacro(DistributeWithMPI, bool); + // Description + // Control if vectors should be generated + // Default is false + void GenerateVectors(int); + vtkGetMacro(GenerateVect, bool); + + // Description + // Control to set is std or mode should be used + // Default is false + void ChangeMode(int); + vtkGetMacro(IsStdOrMode, bool); + + // Description + // Control if a Ghost Cell Generator should be used + // Default is true + void GhostCellGeneratorCallForPara(int); + vtkGetMacro(GCGCP, bool); + + protected: vtkMEDReader(); virtual ~vtkMEDReader(); -- 2.39.2