Plot Tree Timing with MPI

Hello,

I developed a code to run the tree timing code with MPI. I am not familiar with MPI so I get segmentation fault when I call the function.

Thanks

Rafael Scatena

//#ifdef ENABLE_MPI
struct ParallelIsoArgs_tmp
{
  int* RetVal;  // Pointer to store the return value
  int Argc;     // Number of command-line arguments
  char** Argv;  // Array of command-line arguments
  
  vtkCellLocator* CellLocator_mpi;
  vtkCellTreeLocator* CellTreeLocator_mpi;  
  vtkStaticCellLocator* StaticCellLocator_mpi;
  vtkOBBTree* OBBTree_mpi;
  vtkStaticCellLocator* StaticCellLocator;  
  vtkModifiedBSPTree* ModifiedBPSTree_mpi;  
  
      
  vtkMultiProcessController* Controller;
  
  vtkPolyData* Polydata_mpi;  
  LocatorType ChosenLocator_mpi;
  vtkMinimalStandardRandomSequence* Rng_mpi;

  int TotalTime;
  
  int NumberOfTrials;
};




void PlotTreeTimingMPI(vtkSmartPointer<vtkPolyData> polydata_mpi, LocatorType chosenLocator_mpi)
{
    vtkNew<vtkNamedColors> colors;
    vtkMinimalStandardRandomSequence* rng_mpi; rng_mpi->SetSeed(8000000); // rng->SetSeed(8775070);

     std::cout << "Timing Tree MPI..." << std::endl; 
     std::vector<std::pair<int, double>> results;



      int numberOfTrials = 1000;  
   



        
    for(int i= 0; i<16;i++){			  
			  
			  
          double allTimes=0;	    
          int argc_mpi = 0;
          char** argv_mpi = nullptr;

	      
	      vtkCellLocator* cellLocator_mpi;
          vtkCellTreeLocator* cellTreeLocator_mpi;  
          vtkStaticCellLocator* staticCellLocator_mpi;
          vtkOBBTree* oBBTree_mpi;
          vtkStaticCellLocator* staticCellLocator;  
          vtkModifiedBSPTree* modifiedBPSTree_mpi;  

			  
	switch (chosenLocator_mpi) {
			case CELL_LOCATOR:  
			cellLocator_mpi->SetDataSet(polydata_mpi);
			cellLocator_mpi->AutomaticOff();
			cellLocator_mpi->SetMaxLevel(i);
			cellLocator_mpi->UseExistingSearchStructureOn();
			cellLocator_mpi->BuildLocator();break;

			case CELL_TREE_LOCATOR:
			cellTreeLocator_mpi->SetDataSet(polydata_mpi);
			cellTreeLocator_mpi->SetNumberOfBuckets(i);
			cellTreeLocator_mpi->UseExistingSearchStructureOn();
			cellTreeLocator_mpi->BuildLocator();break;

			case STATIC_CELL_LOCATOR:
			staticCellLocator_mpi->SetDataSet(polydata_mpi);
			staticCellLocator_mpi->UseExistingSearchStructureOn();		
			staticCellLocator_mpi->SetMaxLevel(i);
			staticCellLocator_mpi->BuildLocator();break;

			case OBB_TREE:
			oBBTree_mpi->SetDataSet(polydata_mpi);
			oBBTree_mpi->UseExistingSearchStructureOn();
			oBBTree_mpi->AutomaticOff();
			oBBTree_mpi->SetMaxLevel(i);
			oBBTree_mpi->BuildLocator();break;
					
			case MODIFIED_BSP_TREE:
			modifiedBPSTree_mpi->SetDataSet(polydata_mpi);
			modifiedBPSTree_mpi->UseExistingSearchStructureOn();
			modifiedBPSTree_mpi->AutomaticOff();
			modifiedBPSTree_mpi->SetMaxLevel(i);
			modifiedBPSTree_mpi->BuildLocator();break;default:std::cerr << "Unknown Locator Type!" << std::endl;}

      

              // ----------------------------------------------
              int retVal = 1;
              ParallelIsoArgs_tmp args;
              args.RetVal = &retVal;
              args.Argc = argc_mpi;
              args.Argv = argv_mpi;
              args.CellLocator_mpi =  cellLocator_mpi ;
  //            args.CellTreeLocator_mpi =   cellTreeLocator_mpi ;            
 //             args.StaticCellLocator_mpi =  staticCellLocator_mpi; 
  //            args.OBBTree_mpi =   oBBTree_mpi;
 //             args.StaticCellLocator =  staticCellLocator; 
 //             args.ModifiedBPSTree_mpi = modifiedBPSTree_mpi;                      
       

       
              args.Polydata_mpi = polydata_mpi;
              args.Rng_mpi = rng_mpi;
              args.ChosenLocator_mpi = chosenLocator_mpi;
              args.NumberOfTrials = numberOfTrials;
              args.TotalTime = 0;
 
              MPI_Init(&argc_mpi, &argv_mpi);
              vtkMPIController* controller = vtkMPIController::New();
 
//             int numProcesses = controller->GetNumberOfProcesses();
 //            int myRank = controller->GetLocalProcessId();

 
              args.Controller  =controller ;              
             
              controller->Initialize(&argc_mpi, &argv_mpi, 1);
              
              // ----------------------------------------------


              // Pass args to your execution method
              controller->SetSingleMethod(TimeTreeMPI, &args);
              controller->SingleMethodExecute();
           

               double collectedTime;
               collectedTime = args.TotalTime;

                
              controller->Finalize();
              controller->Delete(); 
            

        std::pair<int, double> result(i, collectedTime); results.push_back(result);    std::cout << "Tree no: "<<i <<"  ok!" << std::endl;

            }

	    // Create a table with some points in it.
	    vtkNew<vtkTable> table;

	    vtkNew<vtkFloatArray> maxPointsPerRegion;
	    maxPointsPerRegion->SetName("Max Tree Level");
	    table->AddColumn(maxPointsPerRegion);

	    vtkNew<vtkFloatArray> runtime;
	    runtime->SetName("Run time");
	    table->AddColumn(runtime);
	    
	    
	    // Fill in the table with some example values.
	    size_t numPoints = results.size();
	    table->SetNumberOfRows(static_cast<vtkIdType>(numPoints));
	    for (size_t i = 0; i < numPoints; ++i)
	    {table->SetValue(static_cast<vtkIdType>(i), 0, results[i].first);table->SetValue(static_cast<vtkIdType>(i), 1, results[i].second);}
	    
	    std::pair<int, double> minPair = Tree_Optimization::findMinimum(results);

		// Access the minimum value and its corresponding index
		int minIndex = minPair.first;		double minValue = minPair.second;


	    // Set up the view
	    
		vtkNew<vtkEGLRenderWindow> renderWindow;	renderWindow->OffScreenRenderingOn();
		renderWindow->SetShowWindow(false);	renderWindow->WindowInitialize();
		renderWindow->SetSize(640, 480);
		
		std::string datastructuretype;

	int cells_per_bucket=0;

	switch (chosenLocator_mpi) 
	{case CELL_LOCATOR:renderWindow->SetWindowName("Cell Locator Timing MPI ");datastructuretype = "Cell Locator MPI"; cells_per_bucket = Cell_Locator->GetNumberOfCellsPerBucket();  break;
	case CELL_TREE_LOCATOR:   renderWindow->SetWindowName("Cell Tree Locator MPI"); datastructuretype = "Cell Tree Locator MPI ";cells_per_bucket =Cell_Tree_Locator->GetNumberOfCellsPerNode(); break;
	case STATIC_CELL_LOCATOR: renderWindow->SetWindowName("Static Cell Locator MPI"); datastructuretype = "Static Cell Locator MPI"; cells_per_bucket = Static_Cell_Locator->GetNumberOfCellsPerNode(); break;
	case OBB_TREE:          renderWindow->SetWindowName("OBBTreeTiming Demo"); datastructuretype = "OBB Tree MPI";cells_per_bucket = OBB_Tree->GetNumberOfCellsPerNode();  break;
	case MODIFIED_BSP_TREE: renderWindow->SetWindowName("Modified BSP Tree TimingDemo"); datastructuretype = "Modified BSP Tree MPI ";cells_per_bucket = Modified_BSP_Tree->GetNumberOfCellsPerNode(); break;default:std::cout << "Unknown Locator Type!" << std::endl;}    
		    
	    
		vtkNew<vtkRenderWindowInteractor> interactor;
		interactor->SetRenderWindow(renderWindow);

		vtkNew<vtkContextView> view;
		view->SetRenderWindow(renderWindow);

		// Add multiple line plots, setting the colors etc.
		vtkNew<vtkChartXY> chart;
		view->GetScene()->AddItem(chart);
		
		vtkPlot* line = chart->AddPlot(vtkChart::LINE);
		line->SetInputData(table, 0, 1);
		auto lineColor = colors->HTMLColorToRGBA("Lime").GetData();
		line->SetColor(lineColor[0], lineColor[1], lineColor[2], lineColor[3]);
		line->SetWidth(3.0);
	 
		
	std::string xtitle = "Optimal MPI Level for " + datastructuretype +": "+ std::to_string(minIndex) + "  in "+ std::to_string(minValue) + "s.  " +std::to_string(numberOfTrials) + " trial rays " +"Cells per Node: " + std::to_string(cells_per_bucket);
		
		line->GetXAxis()->SetMinimum(1.0);
		line->GetXAxis()->SetTitle(xtitle.c_str());
		line->GetYAxis()->SetTitle("Run time (seconds)");
		line->GetYAxis()->AutoScale();
		// line->GetYAxis()->SetRange(0,0.02);

		view->GetRenderWindow()->SetMultiSamples(0);    
		// Render and start interactor
		view->GetRenderWindow()->Render();
		interactor->Initialize();
		interactor->Start();

				  // PRINT
		vtkNew<vtkWindowToImageFilter> windowToImageFilter;
		windowToImageFilter->SetInput(renderWindow);
		windowToImageFilter->Update();
				  
		vtkNew<vtkPNGWriter> writer;
		writer->SetFileName(datastructuretype.c_str());
		writer->SetInputConnection(windowToImageFilter->GetOutputPort());
		writer->Write();
		
		}// END TIME A TREE	MPI

The other function is like this:

void  TimeTreeMPI(vtkMultiProcessController* controller, void* arg)
	{  
	

	   ParallelIsoArgs_tmp* args = reinterpret_cast<ParallelIsoArgs_tmp*>(arg);
	   vtkNew<vtkTimerLog> timer; timer->StartTimer();
	   
	
	    // Obtain the id of the running process and the total
	    // number of processes
	

         vtkSmartPointer<vtkPolyData> polydata_mpi= args->Polydata_mpi;

         
	    double p1[3]; double p2[3]; Tree_Optimization::RandomLineThroughVolume(polydata_mpi, p1, p2, args->Rng_mpi);
	    double t; double x[3]; double pcoords[3]; int subId;  double tol = 1.0e-8;
			  

	//RAY INTERSECTION
	switch (args->ChosenLocator_mpi) {
	case CELL_LOCATOR: args->CellLocator_mpi->IntersectWithLine(p1, p2, .001, t, x, pcoords, subId); break;
	case CELL_TREE_LOCATOR: args->CellTreeLocator_mpi->IntersectWithLine(p1, p2, .001, t, x, pcoords, subId);break;
	case STATIC_CELL_LOCATOR:  args->StaticCellLocator_mpi->IntersectWithLine(p1, p2, .001, t, x, pcoords, subId);break;
	case OBB_TREE:  args->OBBTree_mpi->IntersectWithLine(p1, p2, .001, t, x, pcoords, subId);break;
	case MODIFIED_BSP_TREE:  args->ModifiedBPSTree_mpi->IntersectWithLine(p1, p2, .001, t, x, pcoords, subId);break;default:std::cout << "Unknown Locator Type!" << std::endl;}
	
			  
	timer->StopTimer();
//	std::cout << "timer: " << timer->GetElapsedTime()<< " seconds" << std::endl;
	double elapsedTime = timer->GetElapsedTime();


       //GATHER AND PROCESS  	
    
    vtkMPICommunicator* communicator = vtkMPICommunicator::SafeDownCast(args->Controller->GetCommunicator());
    int myRank = communicator->GetLocalProcessId();
    if (myRank != 0) {communicator->Send(&elapsedTime, 1, 0, 123); } // Tag 123 is arbitrary
        else{
        std::vector<double> receivedTimes(args->Controller->GetNumberOfProcesses());
        receivedTimes[0] = elapsedTime; // Root's own elapsed time
        for (int i = 1; i < args->Controller->GetNumberOfProcesses(); ++i) {
            communicator->Receive(&receivedTimes[i], 1, i, 123); // Tag 123 is arbitrary
        }}



      // Prepare the receive buffer only on the root process
        
/*
      if (myid == 0) {
      
      std::vector<double> receiveBuffer;


      receiveBuffer.resize(numberOfTrials * numProcesses);

      // Gather doubles to the root process
        controller->Gather(arg->sendBuffer.data(), receiveBuffer.data(), arg->NumberOfTrials, 0);
        allTimes = 0;
        
              vtkMPIController* control = arg.Controller;
              int numProcesses = control->GetNumberOfProcesses();
        
              for (int i = 0; i < numProcesses; ++i) {allTimes =allTimes + receiveBuffer[i];}}

			  */
			  
			  
			  }//

This code worked. There were several issues including that the intersectwithline function was protected when threaded.

struct ParallelIsoArgs_tmp
{
  int* RetVal;  // Pointer to store the return value
  int Argc;     // Number of command-line arguments
  char** Argv;  // Array of command-line arguments
  
  vtkCellLocator* CellLocator_mpi;
//  vtkCellTreeLocator* CellTreeLocator_mpi;  
//  vtkStaticCellLocator* StaticCellLocator_mpi;
//  vtkOBBTree* OBBTree_mpi;
//  vtkModifiedBSPTree* ModifiedBPSTree_mpi;  
  
      
  vtkMultiProcessController* Controller;
  
  vtkPolyData* Polydata_mpi;  
  LocatorType ChosenLocator_mpi;
  vtkMinimalStandardRandomSequence* Rng_mpi;

  int TotalTime;
  int MaxLevel;
  
  int NumberOfTrials;
};

  TimeTreeMPI(vtkMultiProcessController* controller, void* arg)
{  
	
//	std::cout << "begin mpi!" << std::endl;

	   ParallelIsoArgs_tmp* args = reinterpret_cast<ParallelIsoArgs_tmp*>(arg);
	   vtkNew<vtkTimerLog> timer; timer->StartTimer();
	   
//		std::cout << "args ok!" << std::endl;
		
	    // Obtain the id of the running process and the total
	    // number of processes
	

         vtkSmartPointer<vtkPolyData> polydata_mpi= args->Polydata_mpi;

         
	    double p1[3]; double p2[3]; Tree_Optimization::RandomLineThroughVolume(polydata_mpi, p1, p2, args->Rng_mpi);
	    double t; double x[3]; double pcoords[3]; int subId;  double tol = 1.0e-8; vtkIdType cellId; vtkGenericCell* cell;
	
	vtkPoints* points; vtkIdList* 	cellIds;
	
//			std::cout << "p1:"<<p1[0] << std::endl;		  

          LocatorType choLocator;
        
          choLocator =args->ChosenLocator_mpi;
        
//          vtkCellLocator* cellLocator_mpi;
//          vtkCellTreeLocator* cellTreeLocator_mpi;  
//          vtkStaticCellLocator* staticCellLocator_mpi;
//          vtkOBBTree* oBBTree_mpi;
//          vtkModifiedBSPTree* modifiedBPSTree_mpi;   
          
            vtkNew<vtkCellLocator> cellLocator_mpi;
            
            
//          vtkNew<vtkCellTreeLocator> cellTreeLocator_mpi;  
//          vtkNew<vtkStaticCellLocator> staticCellLocator_mpi;
//          vtkNew<vtkOBBTree> oBBTree_mpi;
//          vtkNew<vtkModifiedBSPTree> modifiedBPSTree_mpi;  
          
        	cellLocator_mpi->SetDataSet(args->Polydata_mpi);
			cellLocator_mpi->AutomaticOff();
			cellLocator_mpi->SetMaxLevel(args->MaxLevel);
			cellLocator_mpi->UseExistingSearchStructureOn();
			cellLocator_mpi->BuildLocator();

	//		std::cout << "locator ok" << std::endl;		  

   //     	cellLocator_mpi->IntersectWithLine(p1,p2,.001,t,x,pcoords,subId,cellId,cell); 
        	cellLocator_mpi->IntersectWithLine(p1,p2,points,cellIds);
	
  
  //			std::cout << "intersect ok"<< std::endl;		        
	//RAY INTERSECTION
//	switch (choLocator) {
//	case CELL_LOCATOR: cellLocator_mpi->IntersectWithLine(p1,p2,.001,t,x,pcoords,subId,cellId,cell); 
//	case CELL_TREE_LOCATOR:  TreeLocator_mpi = args->CellTreeLocator_mpi;
	//                        TreeLocator_mpi->IntersectWithLine(p1,p2,.001,t,x,pcoords,subId,cellId,cell);break;
//	case STATIC_CELL_LOCATOR:   staticLocator_mpi = args->StaticCellLocator_mpi;
	//                           staticLocator_mpi->IntersectWithLine(p1,p2,.001,t,x,pcoords,subId,cellId,cell);break;
//	case OBB_TREE:   oBTree_mpi =  args->OBBTree_mpi;
	//                oBTree_mpi->IntersectWithLine(p1,p2,.001,t,x,pcoords,subId,cellId,cell);break;
//	case MODIFIED_BSP_TREE:   BPSTree_mpi = args->ModifiedBPSTree_mpi;
//	                          BPSTree_mpi->IntersectWithLine(p1,p2,.001,t,x,pcoords,subId,cellId,cell);break;default:std::cout << "Unknown Locator Type!" << std::endl;
//}
	
	
//			std::cout << "Intersect  ok!" << std::endl;
			  
	timer->StopTimer();
//	std::cout << "timer: " << timer->GetElapsedTime()<< " seconds" << std::endl;
	double elapsedTime = timer->GetElapsedTime();


       //GATHER AND PROCESS  	
    

			  
			  
			  }//
			  


void PlotTreeTimingMPI(vtkSmartPointer<vtkPolyData> polydata_mpi, LocatorType chosenLocator_mpi,int argc, char* argv[])
{
    vtkNew<vtkNamedColors> colors;
    vtkNew<vtkMinimalStandardRandomSequence> rng_mpi; rng_mpi->SetSeed(8000000); // rng->SetSeed(8775070);

     std::cout << "Timing Tree MPI..." << std::endl; 
     std::vector<std::pair<int, double>> results;



      int numberOfTrials = 1000;  
   

       //BROADCAST TREE TYPE	



	      vtkNew<vtkCellLocator> cellLocator_mpi;
          vtkNew<vtkCellTreeLocator> cellTreeLocator_mpi;  
          vtkNew<vtkStaticCellLocator> staticCellLocator_mpi;
          vtkNew<vtkOBBTree> oBBTree_mpi;
          vtkNew<vtkModifiedBSPTree> modifiedBPSTree_mpi;  
          
          
    MPI_Init(&argc, &argv);  // Initialize MPI once at the beginning

    vtkMPIController* controller = vtkMPIController::New();
    controller->Initialize(&argc, &argv, 1);  // Initialize controller once at the beginning


        
    for(int i= 1; i<16;i++){	
    
    		  
		switch (chosenLocator_mpi) {
			case CELL_LOCATOR:  
			cellLocator_mpi->SetDataSet(polydata_mpi);
			cellLocator_mpi->AutomaticOff();
			cellLocator_mpi->SetMaxLevel(i);
			cellLocator_mpi->UseExistingSearchStructureOn();
			cellLocator_mpi->BuildLocator();break;

			case CELL_TREE_LOCATOR:
			cellTreeLocator_mpi->SetDataSet(polydata_mpi);
			cellTreeLocator_mpi->SetNumberOfBuckets(i);
			cellTreeLocator_mpi->UseExistingSearchStructureOn();
			cellTreeLocator_mpi->BuildLocator();break;

			case STATIC_CELL_LOCATOR:
			staticCellLocator_mpi->SetDataSet(polydata_mpi);
			staticCellLocator_mpi->UseExistingSearchStructureOn();		
			staticCellLocator_mpi->SetMaxLevel(i);
			staticCellLocator_mpi->BuildLocator();break;

			case OBB_TREE:
			oBBTree_mpi->SetDataSet(polydata_mpi);
			oBBTree_mpi->UseExistingSearchStructureOn();
			oBBTree_mpi->AutomaticOff();
			oBBTree_mpi->SetMaxLevel(i);
			oBBTree_mpi->BuildLocator();break;
					
			case MODIFIED_BSP_TREE:
			modifiedBPSTree_mpi->SetDataSet(polydata_mpi);
			modifiedBPSTree_mpi->UseExistingSearchStructureOn();
			modifiedBPSTree_mpi->AutomaticOff();
			modifiedBPSTree_mpi->SetMaxLevel(i);
			modifiedBPSTree_mpi->BuildLocator();break;
			
			default:std::cerr << "Unknown Locator Type!" << std::endl;}



              double allTimes=0;	    
              int argc_mpi = 0;
              char** argv_mpi = nullptr;

      

              // ----------------------------------------------
              int retVal = 1;
              ParallelIsoArgs_tmp args;
              args.RetVal = &retVal;
              args.Argc = argc;
              args.Argv = argv;
              args.CellLocator_mpi =  cellLocator_mpi ;
  ///            args.CellTreeLocator_mpi =   cellTreeLocator_mpi ;            
 //             args.StaticCellLocator_mpi =  staticCellLocator_mpi; 
 //             args.OBBTree_mpi =   oBBTree_mpi;
 //             args.ModifiedBPSTree_mpi = modifiedBPSTree_mpi;                      
       

       
              args.Polydata_mpi = polydata_mpi;
              args.Rng_mpi = rng_mpi;
              args.ChosenLocator_mpi = chosenLocator_mpi;
              args.NumberOfTrials = numberOfTrials;
              args.TotalTime = 0;
              args.MaxLevel =i;
  //            std::cerr << "args ok!" << std::endl;
 

              vtkMPIController* controller = vtkMPIController::New();
 
 //              std::cerr << "Controler ok!" << std::endl;
//             int numProcesses = controller->GetNumberOfProcesses();
 //            int myRank = controller->GetLocalProcessId();

 
              args.Controller  =controller ;              
             
              controller->Initialize(&argc, &argv, 1);
              
              // ----------------------------------------------

	        vtkNew<vtkTimerLog> timer; timer->StartTimer();

 //             std::cerr << "controler init!" << std::endl;
              // Pass args to your execution method
              controller->SetSingleMethod(TimeTreeMPI, &args);
              controller->SingleMethodExecute();
    
 //                 std::cerr << "controler execute!" << std::endl;       

     //          double collectedTime;
      //         collectedTime = args.TotalTime;

 //             std::cerr << "collected time!" << std::endl;
                
	        timer->StopTimer();
        //	std::cout << "timer: " << timer->GetElapsedTime()<< " seconds" << std::endl;
	        double elapsedTime = timer->GetElapsedTime(); 

              std::cerr << "TIME!: "<< elapsedTime<< std::endl;            

        std::pair<int, double> result(i, elapsedTime); results.push_back(result);    std::cout << "Tree no: "<<i <<"  ok!" << std::endl;

            }
            
              controller->Finalize();
              controller->Delete();

	    // Create a table with some points in it.
	    vtkNew<vtkTable> table;

	    vtkNew<vtkFloatArray> maxPointsPerRegion;
	    maxPointsPerRegion->SetName("Max Tree Level");
	    table->AddColumn(maxPointsPerRegion);

	    vtkNew<vtkFloatArray> runtime;
	    runtime->SetName("Run time");
	    table->AddColumn(runtime);
	    
	    
	    // Fill in the table with some example values.
	    size_t numPoints = results.size();
	    table->SetNumberOfRows(static_cast<vtkIdType>(numPoints));
	    for (size_t i = 0; i < numPoints; ++i)
	    {table->SetValue(static_cast<vtkIdType>(i), 0, results[i].first);table->SetValue(static_cast<vtkIdType>(i), 1, results[i].second);}
	    
	    std::pair<int, double> minPair = Tree_Optimization::findMinimum(results);

		// Access the minimum value and its corresponding index
		int minIndex = minPair.first;		double minValue = minPair.second;


	    // Set up the view
	    
		vtkNew<vtkEGLRenderWindow> renderWindow;	renderWindow->OffScreenRenderingOn();
		renderWindow->SetShowWindow(false);	renderWindow->WindowInitialize();
		renderWindow->SetSize(640, 480);
		
		std::string datastructuretype;

	int cells_per_bucket=0;

	switch (chosenLocator_mpi) 
	{case CELL_LOCATOR:renderWindow->SetWindowName("Cell Locator Timing MPI ");datastructuretype = "Cell Locator MPI"; cells_per_bucket = Cell_Locator->GetNumberOfCellsPerBucket();  break;
	case CELL_TREE_LOCATOR:   renderWindow->SetWindowName("Cell Tree Locator MPI"); datastructuretype = "Cell Tree Locator MPI ";cells_per_bucket =Cell_Tree_Locator->GetNumberOfCellsPerNode(); break;
	case STATIC_CELL_LOCATOR: renderWindow->SetWindowName("Static Cell Locator MPI"); datastructuretype = "Static Cell Locator MPI"; cells_per_bucket = Static_Cell_Locator->GetNumberOfCellsPerNode(); break;
	case OBB_TREE:          renderWindow->SetWindowName("OBBTreeTiming Demo"); datastructuretype = "OBB Tree MPI";cells_per_bucket = OBB_Tree->GetNumberOfCellsPerNode();  break;
	case MODIFIED_BSP_TREE: renderWindow->SetWindowName("Modified BSP Tree TimingDemo"); datastructuretype = "Modified BSP Tree MPI ";cells_per_bucket = Modified_BSP_Tree->GetNumberOfCellsPerNode(); break;default:std::cout << "Unknown Locator Type!" << std::endl;}    
		    
	    
		vtkNew<vtkRenderWindowInteractor> interactor;
		interactor->SetRenderWindow(renderWindow);

		vtkNew<vtkContextView> view;
		view->SetRenderWindow(renderWindow);

		// Add multiple line plots, setting the colors etc.
		vtkNew<vtkChartXY> chart;
		view->GetScene()->AddItem(chart);
		
		vtkPlot* line = chart->AddPlot(vtkChart::LINE);
		line->SetInputData(table, 0, 1);
		auto lineColor = colors->HTMLColorToRGBA("Lime").GetData();
		line->SetColor(lineColor[0], lineColor[1], lineColor[2], lineColor[3]);
		line->SetWidth(3.0);
	 
		
	std::string xtitle = "Optimal MPI Level for " + datastructuretype +": "+ std::to_string(minIndex) + "  in "+ std::to_string(minValue) + "s.  " +std::to_string(numberOfTrials) + " trial rays " +"Cells per Node: " + std::to_string(cells_per_bucket);
		
		line->GetXAxis()->SetMinimum(1.0);
		line->GetXAxis()->SetTitle(xtitle.c_str());
		line->GetYAxis()->SetTitle("Run time (seconds)");
		line->GetYAxis()->AutoScale();
		// line->GetYAxis()->SetRange(0,0.02);

		view->GetRenderWindow()->SetMultiSamples(0);    
		// Render and start interactor
		view->GetRenderWindow()->Render();
		interactor->Initialize();
		interactor->Start();

				  // PRINT
		vtkNew<vtkWindowToImageFilter> windowToImageFilter;
		windowToImageFilter->SetInput(renderWindow);
		windowToImageFilter->Update();
				  
		vtkNew<vtkPNGWriter> writer;
		writer->SetFileName(datastructuretype.c_str());
		writer->SetInputConnection(windowToImageFilter->GetOutputPort());
		writer->Write();
		
		}// END TIME A TREE	MPI

Result:

1 Like