RootMpi Demos
Index
Go to Index
Sphere
In this demonstration I pretend show you how to think a parallel problem and the power of to use RootMpi to solve it using 4 processors exactly.
I want to calculate the parallel surface and volume of a sphere.
Parallel Sphere Volume
To calculate Volume I can calculate $ V=\int\limits_{0}^{r} r^2-(x^2)\,dx. $ . I can calculate it using ROOT::Mpi::Math::TIntegratorWrapper that is RootMpi's class with parallelization ready./*********************************************************************/ /*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);
Parallel Sphere Surface
(wait 5 secs to render latex)To calculate the surface I can express spherical coordinates in rectangular coordinates in this way:
- $x = rcos(\theta)sin(\phi)$
- $y = rsin(\theta)sin(\phi)$
- $z = rcos(\phi)$
Range for process
Process 0 $\phi \in [0,0.5\pi] and\ \theta \in [0,\pi]$
Process 1 $\phi \in [0.5,\pi] and\ \theta \in [0,\pi]$
Process 2 $\phi \in [1,1.5\pi] and\ \theta \in [0,\pi]$
Process 3 $\phi \in [1.5,2\pi] and\ \theta \in [0,\pi]$
In every section I evaluate the intervals with delta=0.01, then I have almost 50000 points in every process.
Every color is the region calculate in different processor, the points are encapsulated in a object TPolyMarker3D and sent to root process(zero) and painted.
Reference
This is the macro for ROOT interpreter.
Go to Index
SphereCode
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 . }
Go to Index
SphereVideo
Reproductor Flash no disponible.
Created by Omar Andres Zapata Mesa.
Voice by Gerardo Gutierrez. (Thanks!)
Go to Index
Parallel Wave Animation
In this demonstration we are going to animate a sin wave. We split it into n-1 processes, the process root(zero) gets the points from other processes and it sends a broadcast with the new angle to calculate the height, and repeat the procedure.WARNING this animation require OpenGL support in your pc.
Go to Index
WaveCode
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 . }
Go to Index
WaveVideo
Reproductor Flash no disponible.
Created by Omar Andres Zapata Mesa.
Voice by Gerardo Gutierrez. (Thanks!)
Go to Index