Salome HOME
Get rid off deepCopy in // mode and limitation of number of requestInformation
authorAnthony Geay <anthony.geay@edf.fr>
Mon, 24 Oct 2022 07:10:44 +0000 (09:10 +0200)
committerAnthony GEAY <anthony.geay@edf.fr>
Wed, 26 Oct 2022 06:33:23 +0000 (08:33 +0200)
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkFileSeriesGroupReader.cxx
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.cxx
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkMEDReader.h

index 31d4702aac9d9671d884dc7b5b20006de9815f93..28f64fcd59a33f59472718e18f95bd6917d00207 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "vtkFileSeriesGroupReader.h"
 
+#include <vtkCollection.h>
 #include <vtkInformation.h>
 #include <vtkInformationVector.h>
 #include <vtkMultiBlockDataSet.h>
@@ -38,6 +39,7 @@ vtkStandardNewMacro(vtkFileSeriesGroupReader);
 struct vtkFileSeriesGroupReaderInternals
 {
   std::vector<std::string> FileNames;
+  vtkNew<vtkCollection> 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<vtkMEDReader> 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<vtkDataObject> outputLeaf = vtkSmartPointer<vtkDataObject>::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;
index ea9ce437fafc633c268ed055170db43bdb74149f..7737fcbbca9a65f0edca75132bbc202dcd0420ac 100755 (executable)
@@ -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 !
index fcf4cc29ada8823e43a05b21967540e90dc50cc1..03b1cb479f12f3fc8ca3d9eb6499c6b7ef25c24e 100755 (executable)
 #include <string>
 
 #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();