/*========================================================================= Program: Visualization Toolkit Module: TestXdmf3Parallel.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // This test exercises xdmf3 reading and writing in parallel. // #include #include "vtkMPICommunicator.h" #include "vtkMPIController.h" #include "vtkNew.h" #include "vtkObjectFactory.h" #include "vtkProcess.h" #include "vtkSmartPointer.h" #include "vtkTestUtilities.h" #include "vtkTesting.h" #include "vtkXdmf3Reader.h" #include "vtkXdmf3Writer.h" #include class MyProcess : public vtkProcess { public: static MyProcess* New(); vtkTypeMacro(MyProcess, vtkProcess); void Execute() override; void SetArgs(int argc, char* argv[], const std::string& ifname, const std::string& ofname) { this->Argc = argc; this->Argv = argv; this->InFileName = ifname; this->OutFileName = ofname; } void CreatePipeline() { int num_procs = this->Controller->GetNumberOfProcesses(); int my_id = this->Controller->GetLocalProcessId(); this->Reader = vtkXdmf3Reader::New(); this->Reader->SetFileName(this->InFileName.c_str()); if (my_id == 0) { cerr << my_id << "/" << num_procs << endl; cerr << "IFILE " << this->InFileName << endl; cerr << "OFILE " << this->OutFileName << endl; } this->Writer = vtkXdmf3Writer::New(); this->Writer->SetFileName(this->OutFileName.c_str()); this->Writer->SetInputConnection(this->Reader->GetOutputPort()); } protected: MyProcess() { this->Argc = 0; this->Argv = nullptr; } int Argc; char** Argv; std::string InFileName; std::string OutFileName; vtkXdmf3Reader* Reader; vtkXdmf3Writer* Writer; }; vtkStandardNewMacro(MyProcess); void MyProcess::Execute() { int proc = this->Controller->GetLocalProcessId(); int numprocs = this->Controller->GetNumberOfProcesses(); this->Controller->Barrier(); this->CreatePipeline(); this->Controller->Barrier(); this->Reader->UpdatePiece(proc, numprocs, 0); this->Writer->Write(); this->Reader->Delete(); this->Writer->Delete(); this->ReturnValue = 1; } int TestXdmf3Parallel(int argc, char** argv) { // This is here to avoid false leak messages from vtkDebugLeaks when // using mpich. It appears that the root process which spawns all the // main processes waits in MPI_Init() and calls exit() when // the others are done, causing apparent memory leaks for any objects // created before MPI_Init(). MPI_Init(&argc, &argv); // Note that this will create a vtkMPIController if MPI // is configured, vtkThreadedController otherwise. vtkNew contr; contr->Initialize(&argc, &argv, 1); int numProcs = contr->GetNumberOfProcesses(); if (numProcs < 2) { cout << "This test requires at least 2 processes" << endl; return EXIT_FAILURE; } vtkMultiProcessController::SetGlobalController(contr); vtkTesting* testHelper = vtkTesting::New(); testHelper->AddArguments(argc, const_cast(argv)); std::string datadir = testHelper->GetDataRoot(); std::string ifile = datadir + "/Data/XDMF/Iron/Iron_Protein.ImageData.xmf"; std::string tempdir = testHelper->GetTempDirectory(); tempdir = tempdir + "/XDMF"; vtksys::SystemTools::MakeDirectory(tempdir.c_str()); std::string ofile = tempdir + "/Iron_Protein.ImageData.xmf"; testHelper->Delete(); // allow caller to use something else for (int i = 0; i < argc; i++) { if (!strncmp(argv[i], "--file=", 11)) { ifile = argv[i] + 11; } } MyProcess* p = MyProcess::New(); p->SetArgs(argc, argv, ifile, ofile); contr->SetSingleProcessObject(p); contr->SingleMethodExecute(); int retVal = p->GetReturnValue(); p->Delete(); contr->Finalize(); vtkMultiProcessController::SetGlobalController(nullptr); if (retVal) { // test passed, remove the files we wrote vtksys::SystemTools::RemoveADirectory(tempdir); } return !retVal; }