/*********************************************************************/ /*Section to calculate volume with parallel multimensional integrator*/ /*********************************************************************/ //integrator creation root's style ROOT::Math::Functor1D function(&sphere_function); ROOT::Math::Integrator integrator; integrator.SetFunction(function); //Mpi's integrator wrapper, integrator from ROOT in one dimension ROOT::Mpi::Math::TIntegratorWrapper MpiIntegrator(&integrator); //integrate in parallel and send the result to rank zero, intervar [0,radius] MpiIntegrator.Integrate(0, 0, radius);
1 . /*******************************************************************************/ 2 . /*Author: Omar Andres Zapata Mesa Ago 2012 */ 3 . /*this example calculate parallel surface's regions in a sphere and the volume.*/ 4 . /*need 4 process to work, beacase the sphere was splitted into four parts. */ 5 . /*******************************************************************************/ 6 . #include <Rtypes.h> 7 . #include <Math/Math.h> 8 . #include <Math/Functor.h> 9 . #include <Math/Integrator.h> 10 . 11 . gSystem->Load("libRMpi"); 12 . 13 . Double_t delta=0.01;//delta to iterate points in the surface 14 . Double_t radius=10; //sphere radius 15 . Double_t radius2=radius*radius; //radius' square 16 . Double_t theta, phi, x,y,z; 17 . Int_t point=0; 18 . /************************************************************************************/ 19 . /*this is the function for positive region of a sphere. use to integrate the volume.*/ 20 . /************************************************************************************/ 21 . Double_t sphere_function(const Double_t param) 22 . { 23 . Double_t x,y; 24 . x=param;//coor x 25 . return 2*M_PI*(radius2-(x*x));//funtion sphere_function(r,x)=V(r,x)= 2*pi*(r2-x2) 26 . } 27 . 28 . void sphere() 29 . { 30 . /********************/ 31 . /*Mpi initialization*/ 32 . /********************/ 33 . ROOT::Mpi::TEnvironment env(gApplication->Argc(), gApplication->Argv()); 34 . ROOT::Mpi::TIntraCommunicator world; 35 . 36 . /*********************************/ 37 . /*Error control, need 4 processes*/ 38 . /*********************************/ 39 . if(world.Size()!=4) 40 . { 41 . std::cout<<"Error: You need run with 4 processes exactly, the sphere was spplitted in four regions. \nExample: mpirun -np 4 root -l sphere.C\n"; 42 . std::cout.flush(); 43 . world.Abort(6); 44 . } 45 . 46 . /*********************************************************************/ 47 . /*Section to calculate volume with parallel multimensional integrator*/ 48 . /*********************************************************************/ 49 . //integrator creation root's style 50 . ROOT::Math::Functor1D function(&sphere_function); 51 . 52 . ROOT::Math::Integrator integrator; 53 . integrator.SetFunction(function); 54 . 55 . //Mpi's integrator wrapper, integrator from ROOT in one dimension 56 . ROOT::Mpi::Math::TIntegratorWrapper MpiIntegrator(&integrator); 57 . 58 . //integrate in parallel and send the result to rank zero, intervar [0,radius] 59 . MpiIntegrator.Integrate(0, 0, radius); 60 . 61 . 62 . /*****************************************************************************************/ 63 . /*this is the root process,calculate the surface z=+qsrt(1−(x2+b2)) for x∈[−1,0],y∈[−1,1]*/ 64 . /*and recv the other surface regions in TPolyMarker3D object from others ranks */ 65 . /*****************************************************************************************/ 66 . if (world.Rank() == 0) { 67 . gBenchmark->Start("sphere"); 68 . // create and open a canvas 69 . TCanvas *canvas = new TCanvas("sphere", "sphere", 300, 10, 700, 500); 70 . canvas->SetFillColor(14); 71 . // creating view 72 . TView *view = TView::CreateView(1, 0, 0); 73 . view->RotateView(90,-10); 74 . view->SetRange(-radius*2, -radius*2, -2*radius, 2*radius, 2*radius, 2*radius); 75 . // create a PolyMarker3D for region/segment 1 calculate in rank 0(this rank) 76 . TPolyMarker3D *surfaceSeg13d = new TPolyMarker3D(); 77 . 78 . for (theta = 0; theta <0.5*M_PI ; theta+= delta) { 79 . for (phi = 0; phi <M_PI; phi += delta) { 80 . 81 . x=radius*cos(theta)*sin(phi); 82 . y=radius*sin(theta)*sin(phi); 83 . z=radius*cos(phi); 84 . // set points 85 . surfaceSeg13d->SetPoint(point, x, y, z); 86 . point++; 87 . } 88 . } 89 . // set marker size, color & style 90 . surfaceSeg13d->SetMarkerSize(1); 91 . surfaceSeg13d->SetMarkerColor(world.Rank() + world.Size()); 92 . surfaceSeg13d->SetMarkerStyle(1); 93 . //drawing region 1 94 . surfaceSeg13d->Draw(); 95 . 96 . //getting region 2 from rank 1 97 . TPolyMarker3D *surfaceSeg23d = new TPolyMarker3D; 98 . world.RecvObject(1, 1, *surfaceSeg23d); 99 . surfaceSeg23d->Draw(); 100 . 101 . //getting region 3 from rank 2 102 . TPolyMarker3D *surfaceSeg33d = new TPolyMarker3D; 103 . world.RecvObject(2, 1, *surfaceSeg33d); 104 . surfaceSeg33d->Draw(); 105 . 106 . //getting region 4 from rank 3 107 . TPolyMarker3D *surfaceSeg43d = new TPolyMarker3D; 108 . world.RecvObject(3, 1, *surfaceSeg43d); 109 . surfaceSeg43d->Draw(); 110 . 111 . Char_t timeStr[60]; 112 . Char_t pointsStr[100]; 113 . Char_t radiusStr[100]; 114 . Char_t deltaStr[100]; 115 . gBenchmark->Show("sphere"); 116 . 117 . Float_t ct = gBenchmark->GetCpuTime("sphere"); 118 . sprintf(timeStr, "Execution time: %g sec.", ct); 119 . sprintf(radiusStr, "Radius : %g", radius); 120 . sprintf(deltaStr, "Delta : %g", delta); 121 . sprintf(pointsStr, "Total surface points : %g", point*4); 122 . 123 . TPaveText *text = new TPaveText(0.1, 0.6, 0.9, 0.99); 124 . text->SetFillColor(42); 125 . text->AddText("ROOTMpi example: sphere.C"); 126 . text->AddText(timeStr); 127 . text->AddText(radiusStr); 128 . text->AddText(deltaStr); 129 . text->AddText(pointsStr); 130 . text->Draw(); 131 . 132 . //sphere volume V=(4/3)*pi*r3 133 . //and compare the result integration's volume 134 . Char_t volumeStr[100]; 135 . Double_t volume= MpiIntegrator.Result(); 136 . Double_t volumeTeo=(4/3.0)*M_PI*(radius*radius*radius); 137 . 138 . sprintf(volumeStr, "Volumen with integration = %.15g \nVolumen with (4/3)*pi*r3 = %.15g", volume,volumeTeo); 139 . 140 . TPaveText *volumeText = new TPaveText(-0.1, -0.81, -0.9, -0.97); 141 . volumeText->SetFillColor(41); 142 . volumeText->SetTextAlign(11); 143 . volumeText->AddText(volumeStr); 144 . volumeText->Draw(); 145 . } 146 . /*************************************************************************/ 147 . /*this rank calculate the surface for theta ∈[0.5pi,pi] and phi ∈[0,pi] */ 148 . /*and send the surface regions in TPolyMarker3D object to rank root zero */ 149 . /*************************************************************************/ 150 . if (world.Rank() == 1) { 151 . TPolyMarker3D *surfaceSeg23d = new TPolyMarker3D(); 152 . 153 . for (theta = 0.5*M_PI; theta <M_PI ; theta+= delta) { 154 . for (phi = 0; phi <M_PI; phi += delta) { 155 . 156 . x=radius*cos(theta)*sin(phi); 157 . y=radius*sin(theta)*sin(phi); 158 . z=radius*cos(phi); 159 . // set points 160 . surfaceSeg23d->SetPoint(point, x, y, z); 161 . point++; 162 . } 163 . } 164 . // set marker size, color & style 165 . surfaceSeg23d->SetMarkerSize(1); 166 . surfaceSeg23d->SetMarkerColor(world.Rank() + world.Size()); 167 . surfaceSeg23d->SetMarkerStyle(1); 168 . //send surface points to root process 169 . world.SendObject(0, 1, *surfaceSeg23d); 170 . } 171 . /*************************************************************************/ 172 . /*this rank calculate the surface for theta ∈[pi,1.5pi] and phi ∈[0,pi] */ 173 . /*and send the surface regions in TPolyMarker3D object to rank root zero */ 174 . /*************************************************************************/ 175 . if (world.Rank() == 2) { 176 . TPolyMarker3D *surfaceSeg33d = new TPolyMarker3D(); 177 . for (theta = M_PI; theta <1.5*M_PI ; theta+= delta) { 178 . for (phi = 0; phi <M_PI; phi += delta) { 179 . 180 . x=radius*cos(theta)*sin(phi); 181 . y=radius*sin(theta)*sin(phi); 182 . z=radius*cos(phi); 183 . // set points 184 . surfaceSeg33d->SetPoint(point, x, y, z); 185 . point++; 186 . } 187 . } 188 . // set marker size, color & style 189 . surfaceSeg33d->SetMarkerSize(1); 190 . surfaceSeg33d->SetMarkerColor(world.Rank() + world.Size()); 191 . surfaceSeg33d->SetMarkerStyle(1); 192 . //send surface points to root process 193 . world.SendObject(0, 1, *surfaceSeg33d); 194 . } 195 . /*************************************************************************/ 196 . /*this rank calculate the surface for theta ∈[1.5pi,2pi] and phi ∈[0,pi] */ 197 . /*and send the surface regions in TPolyMarker3D object to rank root zero */ 198 . /*************************************************************************/ 199 . if (world.Rank() == 3) { 200 . TPolyMarker3D *surfaceSeg43d = new TPolyMarker3D(); 201 . for (theta = 1.5*M_PI; theta <2*M_PI ; theta+= delta) { 202 . for (phi = 0; phi <M_PI; phi += delta) { 203 . 204 . x=radius*cos(theta)*sin(phi); 205 . y=radius*sin(theta)*sin(phi); 206 . z=radius*cos(phi); 207 . // set points 208 . surfaceSeg43d->SetPoint(point, x, y, z); 209 . point++; 210 . } 211 . } 212 . // set marker size, color & style 213 . surfaceSeg43d->SetMarkerSize(1); 214 . surfaceSeg43d->SetMarkerColor(world.Rank() + world.Size()); 215 . surfaceSeg43d->SetMarkerStyle(1); 216 . //send surface points to root process 217 . world.SendObject(0, 1, *surfaceSeg43d); 218 . } 219 . }
1 . /*******************************************************************************/ 2 . /*Author: Omar Andres Zapata Mesa Ago 2012 */ 3 . /*this example calculate parallel wave animation */ 4 . /*work with any number(n) of processes but the wave is splitted into n-1 parts */ 5 . /*******************************************************************************/ 6 . #include <Rtypes.h> 7 . #include <Math/Math.h> 8 . #include <TF1.h> 9 . #include <TPolyMarker3D.h> 10 . Double_t delta=0.1; 11 . Double_t min=0,max=6*M_PI; 12 . Double_t angle=M_PI; 13 . Double_t init,end; 14 . Int_t counter=0; 15 . 16 . UInt_t rep=1000; 17 . UInt_t delay=100; 18 . 19 . UInt_t MPI_SUCCESS=0; 20 . /********************/ 21 . /*Mpi initialization*/ 22 . /********************/ 23 . ROOT::Mpi::TEnvironment env(gApplication->Argc(), gApplication->Argv()); 24 . ROOT::Mpi::TIntraCommunicator world; 25 . 26 . TCanvas *canvas = NULL; 27 . TView *view = NULL; 28 . 29 . 30 . void Init() 31 . { 32 . gStyle->SetCanvasPreferGL(true); 33 . gStyle->SetFrameFillColor(42); 34 . canvas = new TCanvas("canvas", "wave", 300, 10, 700, 500); 35 . canvas->SetFillColor(14); 36 . view = TView::CreateView(1, 0, 0); 37 . view->RotateView(90,0); 38 . } 39 . 40 . void Animate() 41 . { 42 . if (!gROOT->GetListOfCanvases()->FindObject("canvas")){ 43 . world.Abort(MPI_SUCCESS); 44 . }; 45 . gPad->Clear(); 46 . for(int i=1;i<world.Size();i++) 47 . { 48 . //getting wave sections from ranks>1 49 . TPolyMarker3D *Section = new TPolyMarker3D(); 50 . world.RecvObject(i, 1, *Section); 51 . Section->Draw(); 52 . } 53 . gPad->Modified(); 54 . gPad->Update(); 55 . angle += 0.05*M_PI; 56 . world.BcastSendScalar(angle,0); 57 . counter++; 58 . if(counter<rep) world.BcastSendScalar(true,0); 59 . else world.BcastSendScalar(false,0); 60 . } 61 . 62 . 63 . void wave() 64 . { 65 . 66 . /**************************************************/ 67 . /*rank zero(root) dont calculate wave, init viewer*/ 68 . /*and recv wave sections from other processes */ 69 . /**************************************************/ 70 . if (world.Rank() == 0) { 71 . Init(); 72 . TTimer *timer = new TTimer(delay); 73 . timer->SetCommand("Animate()"); 74 . Char_t timeStr[60]; 75 . Char_t pointsStr[100]; 76 . Char_t deltaStr[100]; 77 . timer->TurnOn(); 78 . }else{ 79 . Double_t step = fabs(min - max) / (world.Size()-1); 80 . 81 . init = min + (world.Rank()-1) * step; 82 . end = init + step; 83 . cout<<"rank="<<world.Rank()<<" init="<<init<<" end="<<end<<"\n"; 84 . Int_t flag=true; 85 . while(flag){ 86 . TPolyMarker3D *Section=new TPolyMarker3D(); 87 . counter=0; 88 . for(Double_t t=init;t<end;t+=delta) 89 . { 90 . Section->SetPoint(counter,t,sin(t+angle),0); 91 . counter++; 92 . } 93 . // set marker size, color & style 94 . Section->SetMarkerSize(1); 95 . Section->SetMarkerColor(world.Rank()); 96 . Section->SetMarkerStyle(8); 97 . //send segment of points to root process 98 . world.SendObject(0, 1, *Section); 99 . 100 . world.BcastRecvScalar(angle,0); //recv angle to wave evolution 101 . world.BcastRecvScalar(flag,0);//recv flag to stop 102 . delete Section; 103 . } 104 . world.Abort(MPI_SUCCESS); 105 . } 106 . }
El documento original está disponible en https://clustercien.udea.edu.co/web/tiki-index.php?page=RootMpi+Demos