Lygagreč ų r paskrstytų skač avmų praktns darbas - OpenMP r OpenMPI naudomas 1
Turnys Įvadas... 3 1. Boutklo modelo šlygaretnmas... 4 Matemetns models... 4 Skatns models... 5 Lygagretnmas... 6 2. Nuosekluss algortmas... 7 3. Realzaca OpenMP... 9 4. Realzaca OpenMPI... 1 5. Rezultata... 12 Rezultatų aptarams r švados... 13 6. Preda... 14 Nuosekl programa... 14 OpenMP programa... 15 OpenMP paledmo skrptas... 17 OpenMPI programa... 17 OpenMPI paledmo skrptas... 21 2
Įvadas Darbe nagrnėama boutklo modelavmo šlygagretnmo uždavnys naudoant OpenMP r OpenMPI technologas. Prmame skyrue aptaramas boutklo models, be nagrnėama šlygagretnmo galmybė. Antrame skyrue patekams nuoseklus algortmas. Trečame skyrue aptarma realzaca OpenMP. Ketvrtame skyrue aptarama realzaca OpenMPI. Penktame skyrue patekam lygagrečųų algormų vekmo rezultata. Skyrue Preda patekam realzacos koda be paledmo VU superkomputerye skrpta. 3
1. Boutklo modelo šlygaretnmas Matemetns models Boutkls įrengnys matuoants medžagų koncentracą trpale. Labausa papltęs ampermetrns boutkls: naudoant fermentą (E) konvertuoa matuoamą medžagą (S) į produktą (P): E S P, kurs savo ruoštu dalyvaua katodnėe-anodnėe reakcoe. Įrengnye palakoma pastov įtampa r matuoama elektros srovės stprs. Apermetrno boutklo models aprašo dfuzą r fermentnę reakcą. Gauname lygts: S t = D 2 S S x 2 V maxs K M + S P t = D 2 P P x 2 + V maxs K M + S, < x < d, < t T, < x < d, < t T ča V max - maksmalus reakcos grets pasekamas, ka pasrnktam fermento keku trpalas plna įsotnamas substratu (matuoama trpalo medžaga) S, K M Mchaelo konstanta, S - substrato koncentraca, P produkto koncentraca, d - bologška aktyvaus komponento stors, t lakas, T boutklo vekmo lakas, D S r D P dfuzos koefcenta. Boutkls pradeda vekt, ka substratas (matuoama trpalo medžaga) patenka ant bologška aktyvaus komponento pavršaus. Ta nusakoma pradnėms sąlygoms (t = ): S (x, ) = {, x < d, S, x = d, P (x, ) =, x d ča S substrato (matuoamos medžagos) S koncentraca ant boutklo pavršaus. Krašnės sąlygos, nusako substrato rbomasį su boutklo šore be produkto lasvą dfuza kraštuose: S x x= =, S (d, t) = S P (, t) = P (d, t) =, Boutklo srovės stpro tanks lako momentu t gaunamas š Faradėaus dėsno [Sch9]: I (t) = n e FD P P x x= k = 1,, K, 4
ča n e - elektronų keks, dalyvauants įkrovos perdavme ant elektrodo pavršaus, F Faradėaus konstanta. Skatns models Gautas matematns models sprendžamas bagtnų skrtumų metodu, naudoant šrekštnę shemą. Kad rast skatnį sprendnį srtye [, d] [, T], buvo panaudota tolyd ω h ω τ gardelė: Šame darbe naudoamas žymėmas: ω h = {x : x = h, =,, N 1 ; hn 1 = d, ω τ = {t : t = τ, =,, N 2 ; τn 2 = T. S = S(x, t ), P = P(x, t ), =,, N 1 ; =,, N 2 Aproksmant dferencalus bagtnas skrtumas, lygtms sudarytos šrekštnės bagtnų skrtumų shemos: S +1 S τ P +1 P τ S = D +1 S P = D +1 P 2S + S 1 h 2 2P + P 1 h 2 = 1,, N 1 1, = 1,, N 2 1. V maxs K M + S, + V maxs K M + S, Duoto shema yra šrekštnė. Išrekškme vršutnės elės elementus žemesnas elementas: S +1 = S S + τ (D +1 S 2S + S 1 h 2 V maxs K M + S ), P +1 = P P + τ (D +1 P 2P + P 1 h 2 + V maxs K M + S ). (1) Pradnes sąlygas aproksmuoame: = 1,, N 1 1, = 1,, N 2 1. S =, =,, N 1 1; S N1 = S, P =, =,, N 1. (2) Kraštnės sąlygos aproksmuoamos: 5
S = S 1, = 1,, N 2, S N1 =, = 1,, N 2, (3) P =, P N1 =, = 1,, N 2, Turnt skatnį sprendmą, boutklo generuoamos srovės stpro tanks lako momentu t randamas: I(t ) = n e FD P (P 1 P )/h, =,, N 2. (4) Lygagretnmas Dskrečoo tnklo ω h ω τ t r t +1 lyga be ų prklausomybės atrodo tap: t N2 N S 2 N S 2 2 N 2 N 2 N 2 S 1 S S+1 N 2 S+2 N S 2 N1 t +1 +1 S +1 S 2 +1 S 1 S +1 +1 S +1 +1 S +1 +2 S N1 t S S 2 S 1 S S +1 S +2 S N1 t S S 2 S 1 S S +1 S +2 S N1 Juoda lna žymma S +1 prklausomybė nuo S 1, S, S +1. Pradnės sąlygos ledža suskačuot sprendnį pradnu lako momentu t = t =. Turnt sprendnį t lako momentu, sprendnys t +1 +1 randamas naudoant šrekštnę schemą be kraštnes sąlygas. Sprendnų S =,, N 1 šskačavmas gal būt šlygagretnmas, nes atskr procesora naudodames tk S 1, S, S +1 elementas gal neprklausoma apskačuot savo elemetus S +1 = n m,, n m+1. Padalnant vsems procesorams venoda elemtų, gauname, kad m-ass procesorus (š vso M procesorų, ty m =,, M 1) skačuoa elemetus nuo n m = m N 1 /M k n m+1 = 1 + (m + 1) N 1 /M. Pastaba: analogškas samprotavmas galoa r P. 6
2. Nuosekluss algortmas Prmame skyrue aprašytas skatns sprendmas buvo realzuotas C programavmo kalba: ča masyve S saugomos S, =,, N 1 rekšmės, o masyve S_new saugomos S +1, =,, N 1 rekšmės (attnkma P r P_new saugo P r P +1 rekšmes). Ktų kntamųų pavadnma ntutyva suvokam. Kekvno cklo pabagoe S masyvu prskarame S_new rekšmę (tap pat P r P_new). Cklas: skačuoa S +1, = 1,, N 1 1 rekšmes pagal (1) šrekštnę shemą (tap pat P +1 ). Prskrmo sakna: 7
aproksmuoa kraštnes sąlygas (3). Pradnu lako momentu rekšmės ncalzuoamos pagal pradnes sąlygas (2) : Sąlygns saknys: kas sekundę skačuoa boutklo generuoamos srovės tankį pagal (4). 8
3. Realzaca OpenMP OpenMP technologa ledžant lygagreča programuot, naudoant tam tkras komplatoraus drektyvas. Š technologa naudoa bendrą operatyvnę atmntį (RAM). Pranašumas, kad gana paprasta paprastą programą skrta nuoseklam komputeru perdrbt lygagrečaam komputeru. Iš esmės toka stratega buvo takyta šame darbe: pradžo parašyta nuosekl boutklo modelavmo programa, kur po to, naudoant komplatoraus drektyvas buvo perdrbta į lygagrečaą. Pateksme cklą, kurs randa sprendnį t +1 lako momentu, ka turmas sprendnys t lako momentu: Duotaeme algortme patektos komplatoraus drektyvos šlygagretnančos vdnį cklą. Drektyva: #pragma omp parallel shared(s_new,p_new,s,p) prvate(), nurodo, kad prasdeda lygagrečo srts, knteme: S_new,P_new,S,P yra bendr, o kntamass yra prvatus. Drektyva: #pragma omp for schedule(statc,chunk), nurodo, kad tolau enantį cklą galma skačuot kelas procesoras: kekvenas procesorus įvykdys chunk cklo teracų. Kek teracų vykdyt paskačuoame rešknu: nt chunk=floor(n/omp_get_num_threads())+1;. Šos programmos vekmo rezultata patekt skyrue Rezultata. 9
4. Realzaca OpenMPI OpenMPI pranešmas paremta technologa, kekvenas procesas tur savo procesorų r atskrą atmntį (RAM). Šos tehcnologos trūkumas, kad programuotou sudėtngau realzuot algortmą, lygnant su OpenMP be pranešmų suntmas gal parekalaut daug lako. Iš ktos pusės procesa autonomškesn, nes tur savo atmntį, tad galma ralzuot įvaresnų lygagrečųų schemų. Boutklo skatno sprendno realzaca naudoant OpenMPI paremta tuo paču lygagretnmo prncpu patektu skyrue Boutklo modelo šlygaretnmas, ty askr procesa skačuoa savo elemetus: S +1 = n m,, n m+1, kur n m = m N 1 /M k n m+1 = 1 + (m + 1) N 1 /M, ča m = M, procesorų skačus M. Procesu m apskačavus savo dalį, s pasunča krašnus elementus: S +1 nm, S +1 nm+1, attnkmama kamynnams procesams m-1 r m+1, be gauna š kamynnų procesų m-1 r m+1 attnkama elementus: S +1 +1 nm 1, S nm+1 +1, žr. shemą (pastaba: rodyklės vazduoa procesų apsketmą): t +1 +1 S +1 S nm 1 +1 S nm +1 S nm+1 +1 S +1 nm+1 +1 S N1 t S S nm 1 S nm S nm+1 S nm+1 +1 S N1 Įvykžus tokį apsketmą galma tolau tęst algortmą r skačuot S +2 = n m,, n m+1 elementus Pastaba: analogškas samprotavmas galoa r P. Kadang pats skačavmo cklas au buvo aptartas, šame skyrue aptarsme tk duomenų apsketmą (plnas programos kodas patektas skyrue Preda). Apsketmo kraštnas elementas kodas: 1
ča kntamass myrank attnka m. Pradžoe atlekame tkrnmą ar proceso numers lygns ar ne: f(myrank%2==){ e lygns procesas prma sunča duomens, po to uo gauna š kamynų. Je nelygns vyksta atvrkščas procesas ta daroma tam, kad nepklūt į aklgatvį (angl. deadlock). Funkca MPI_Isend vykdo neblokuotą suntmą, o funkca MPI_Irecv vykdo neblokuotą gavmą, t.y. įvykdžus šas funkcas vykdomos sekančos programos komandos, nelaukant suntmo-gavmo pabagos. Kad snchronzuot procesų vekmą naudoma funkca: MPI_Watall(2,request_arr,status_arr);, š funkca baga darbą tk tada, ka įvykdom vs užklausma esantys masyve request_arr. Šos programmos vekmo rezultata patekt skyrue Rezultata. 11
Lakas, s 5. Rezultata Nagrnėtos programos buvo ledžamos VU superkomputerye su skrtngas procesorų skačas. Kad gaut palygnamus rezultatus vs skačavma buvo vykdom beta telkno mazguose. OpenMP r OpenMPI vekmo rezultata: 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 1 11 12 13 14 Procesorų skačus OpenMP OpenMPI 1 pav. OpenMP r OpenMPI vekmo rezultata kečant procesorų skačų. Pastaba: rezultatuose, ka naudoamas 1 procesorus, patekamas nuoseklaus algortmo vekmo lakas. Iš esmės rezultata panašūs: grečausa boutkls susmuluoamas OpenMPI programa naudoant 1 procesorų: 25 s. (OpenMP programa tap pat grečausa veka su 1 procesorų: 29 s.). Lygagrečoo algortmo efektyvumo kefcentas apbrėžamas: E p = S p p = T T p p ča p procesorų skačus, S p spartnmo koefcntas, T nuoseklaus algortmo vykdymo laaks, T p lygagretaus algortmo naudoant P procesorų vykdymo lakas. Efektyvausa šnaudoam procesora, ka: p = arg max E p Suoptmzavus gauname (žr. 3 pav), kad OpenMP atveu - p=2 (E p = T OpenMPI atveu - p=2 (E p = 79 49 2 T p p = 79 56 2 =,71), tap pat =,81). Bee OpenMPI atveu procesora efektyvau šnaudoam. 12
Efektyvumo koefcantas Spartnmo koefcntas 3.5 3 2.5 2 1.5 1 OpenMP OpenMPI.5 2 3 4 5 6 7 8 9 1 11 12 13 14 Procesorų skačus 2 pav. OpenMP r OpenMPI spartnmo koefcenta kečant procesorų skačų..9.8.7.6.5.4.3 OpenMP OpenMPI.2.1 2 3 4 5 6 7 8 9 1 11 12 13 14 Procesorų skačus 3pav. OpenMP r OpenMPI efektyvumo kefcentas kečant procesorų skačų. Rezultatų aptarams r švados Nagrneamą boutklo modelį gerau pavyko realzuot OpenMPI technologa, nes tek sparčausa įvykdoma smulaca (ka P=1 lakas 25 s.), tek efektyvausa šnaudoam procesora (ka p=2 efektyvumo kefcentas E p =,81). Iš ktos pusės OpenMP daug paprastesnė realzaca, tad daugelu atveu taupant programuotoo darbo laką, matyt verta rnkts OpenMP technologą. 13
6. Preda Nuosekl programa #nclude <stdo.h> #nclude <stdlb.h> #nclude <tme.h> #defne tau.1 #defne h.1 #defne d.2 #defne D 3E-6 #defne Vmax 1.E-7 #defne Km 1E-7 #defne S 32E-1 #defne ne 2 #defne F 96485 #defne T 3 /*#defne tau.1 #defne h.1*/ nt man() { nt const N=(nt)(d/h); double *S=(double*) malloc (N*szeof(double)); double *P=(double*) malloc (N*szeof(double));; double *S_new=(double*) malloc (N*szeof(double)); double *P_new=(double*) malloc (N*szeof(double)); double *Tmp1,*Tmp2; double I; nt, 1; tme_t tmer1, tmer2; tme(&tmer1); /*ntalse: */ for(=;<n;++){ S[]=; P[]=; S[N-1]=S; /*compute: */ for(1=;1*tau<=t;1++){ for(=1;<n-1;++){ S_new[]=S[]+tau*(D*(S[+1]-2*S[]+S[-1])/(h*h) - Vmax*S[]/(Km+S[])); P_new[]=P[]+tau*(D*(P[+1]-2*P[]+P[-1])/(h*h) + Vmax*S[]/(Km+S[])); S_new[]=S_new[1]; S_new[N-1]=S; P_new[]=; P_new[N-1]=; f(floor((1-1)*tau)!=floor(1*tau)){ I=ne*F*D*(P_new[1]-P_new[])/h; prntf(" %d %E\n",(nt)(1*tau),I); 14
Tmp1=S_new; Tmp2=P_new; S_new=S; P_new=P; S=Tmp1; P=Tmp2; prntf("hello world!\n %e",i); prntf("analtns atsakymas pre mazu koncentracu:%e \n",(ne*f*d*(s/d)*(1-1/(cosh(d*sqrt(vmax/(km*d))))))); prntf("analtns atsakymas pre ddelu koncentracu:%e \n",(ne*f*vmax*d)/2); tme(&tmer2); prntf("lakas: %f", dfftme (tmer2,tmer1)); return ; OpenMP programa #nclude <stdo.h> #nclude <stdlb.h> #nclude <tme.h> #nclude <math.h> #nclude <omp.h> #defne tau.5 #defne h.5 #defne d.2 #defne D 3E-6 #defne Vmax 1.E-7 #defne Km 1E-7 #defne S 32E-1 #defne ne 2 #defne F 96485 #defne T 3 vod calc(nt num_proc); /*#defne tau.1 #defne h.1*/ nt man() { calc(1); calc(4); calc(6); return ; vod calc(nt num_proc){ nt nthreads,td; nt const N=(nt)(d/h); 15
double *S=(double*) malloc (N*szeof(double)); double *P=(double*) malloc (N*szeof(double));; double *S_new=(double*) malloc (N*szeof(double)); double *P_new=(double*) malloc (N*szeof(double)); double *Tmp1,*Tmp2; double I; nt, 1; tme_t tmer1, tmer2; tme(&tmer1); omp_set_num_threads(num_proc); /*ntalse: */ for(=;<n;++){ S[]=; P[]=; S[N-1]=S; prntf("\n"); /*compute: */ for(1=;1*tau<=t;1++){ #pragma omp parallel shared(s_new,p_new,s,p) prvate() { nt chunk=floor(n/omp_get_num_threads())+1; #pragma omp for schedule(statc,chunk) for(=1;<n-1;++){ S_new[]=S[]+tau*(D*(S[+1]-2*S[]+S[-1])/(h*h) - Vmax*S[]/(Km+S[])); P_new[]=P[]+tau*(D*(P[+1]-2*P[]+P[-1])/(h*h) + Vmax*S[]/(Km+S[])); S_new[]=S_new[1]; S_new[N-1]=S; P_new[]=; P_new[N-1]=; f(floor((1-1)*tau)!=floor(1*tau)){ I=ne*F*D*(P_new[1]-P_new[])/h; /*prntf(" %d %E\n",(nt)(1*tau),I);*/ Tmp1=S_new; Tmp2=P_new; S_new=S; P_new=P; S=Tmp1; P=Tmp2; prntf("srove:%e\n ",I); prntf("analtns atsakymas pre mazu koncentracu:%e \n",(ne*f*d*(s/d)*(1-1/(cosh(d*sqrt(vmax/(km*d))))))); 16
prntf("analtns atsakymas pre ddelu koncentracu:%e \n",(ne*f*vmax*d)/2); tme(&tmer2); prntf("lakas: %f\n", dfftme (tmer2,tmer1)); #pragma omp parallel { #pragma omp sngle prntf("procesoru sk.: %d\n",omp_get_num_threads()); OpenMP paledmo skrptas #!/bn/sh #SBATCH -p short #SBATCH -C beta #SBATCH -c12 gcc -fopenmp -lm -o man man.c./man OpenMPI programa #nclude <stdo.h> #nclude <stdlb.h> #nclude <tme.h> #nclude <math.h> #nclude <mp.h> #defne tau.2 #defne h.2 #defne d.2 #defne D 3E-6 #defne Vmax 1.E-7 #defne Km 1E-7 #defne S 32E-1 #defne ne 2 #defne F 96485 #defne T 3 #defne MAX_WORK 2 nt man(nt argc, char **argv) { nt const N=(nt)(d/h); double *S=(double*) malloc (N*szeof(double)); double *P=(double*) malloc (N*szeof(double));; double *S_new=(double*) malloc (N*szeof(double)); double *P_new=(double*) malloc (N*szeof(double)); double *Tmp1,*Tmp2; double I; nt, 1; nt num_ter; nt myrank, numprocs; double work[max_work]; double work2[max_work]; 17
MPI_Status status_arr[2]; MPI_Datatype param_rowtype; MPI_Request request_arr[2]; tme_t tmer1, tmer2; tme(&tmer1); MPI_Int(&argc, &argv); MPI_Type_contguous(MAX_WORK, MPI_DOUBLE, ¶m_rowtype); MPI_Type_commt(¶m_rowtype); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); MPI_Comm_sze(MPI_COMM_WORLD, &numprocs); num_ter=n/numprocs+1; f(num_ter*(numprocs-1)>=n-3){ prntf("klada!!!!!!!!\n"); MPI_Fnalze(); return ; num_ter--; nt ter_mn=myrank==?1:myrank*num_ter; nt ter_max=myrank==numprocs-1?n-1:(myrank+1)*num_ter; /*ntalse: */ for(=;<n;++){ S[]=; P[]=; S[N-1]=S; /*compute: */ for(1=;1*tau<=t;1++){ for(=ter_mn;<ter_max;++){ S_new[]=S[]+tau*(D*(S[+1]-2*S[]+S[-1])/(h*h) - Vmax*S[]/(Km+S[])); P_new[]=P[]+tau*(D*(P[+1]-2*P[]+P[-1])/(h*h) + Vmax*S[]/(Km+S[])); f(ter_mn==1){ f(floor((1-1)*tau)!=floor(1*tau)){ I=ne*F*D*(P_new[1]-P_new[])/h; prntf(" %d %E\n",(nt)(1*tau),I); S_new[]=S_new[1]; P_new[]=; work[]=s_new[ter_max-1]; work[1]=p_new[ter_max-1]; MPI_Isend(work,/*msg buf*/ 1,/*one data tem*/ param_rowtype,/*type*/ myrank+1,/*dest prc*/ 1, /* msg tag*/ MPI_COMM_WORLD, &request_arr[]); /*def comm*/ MPI_Watall(1,request_arr,status_arr); MPI_Irecv(work, 1, param_rowtype, myrank+1, MPI_ANY_TAG, MPI_COMM_WORLD, &request_arr[]); MPI_Watall(1,request_arr,status_arr); S_new[ter_max]=work[]; P_new[ter_max]=work[1]; 18
else f(ter_max==n-1){ S_new[N-1]=S; P_new[N-1]=; f(myrank%2==){ work[]=s_new[ter_mn]; work[1]=p_new[ter_mn]; MPI_Isend(work,/*msg buf*/ 1,/*one data tem*/ param_rowtype,/*type*/ myrank-1,/*dest prc*/ 1, /* msg tag*/ MPI_COMM_WORLD, &request_arr[]); /*def comm*/ MPI_Watall(1,request_arr,status_arr); MPI_Irecv(work, 1, param_rowtype, myrank-1, MPI_ANY_TAG, MPI_COMM_WORLD, &request_arr[]); MPI_Watall(1,request_arr,status_arr); S_new[ter_mn-1]=work[]; P_new[ter_mn-1]=work[1]; else{ MPI_Irecv(work, 1, param_rowtype, myrank-1, MPI_ANY_TAG, MPI_COMM_WORLD, &request_arr[]); MPI_Watall(1,request_arr,status_arr); S_new[ter_mn-1]=work[]; P_new[ter_mn-1]=work[1]; work[]=s_new[ter_mn]; work[1]=p_new[ter_mn]; MPI_Isend(work,/*msg buf*/ 1,/*one data tem*/ param_rowtype,/*type*/ myrank-1,/*dest prc*/ 1, /* msg tag*/ MPI_COMM_WORLD, &request_arr[]); /*def comm*/ MPI_Watall(1,request_arr,status_arr); else{ f(myrank%2==){ work[]=s_new[ter_mn]; work[1]=p_new[ter_mn]; MPI_Isend(work,/*msg buf*/ 1,/*one data tem*/ param_rowtype,/*type*/ myrank-1,/*dest prc*/ 1, /* msg tag*/ MPI_COMM_WORLD, &request_arr[]); /*def comm*/ work2[]=s_new[ter_max-1]; work2[1]=p_new[ter_max-1]; MPI_Isend(work2,/*msg buf*/ 1,/*one data tem*/ param_rowtype,/*type*/ myrank+1,/*dest prc*/ 1, /* msg tag*/ MPI_COMM_WORLD,&request_arr[1]); /*def comm*/ MPI_Watall(2,request_arr,status_arr); MPI_Irecv(work, 1, param_rowtype, myrank+1, MPI_ANY_TAG, MPI_COMM_WORLD, &request_arr[]); MPI_Irecv(work2, 1, param_rowtype, myrank-1, MPI_ANY_TAG, MPI_COMM_WORLD, &request_arr[1]); MPI_Watall(2,request_arr,status_arr); S_new[ter_max]=work[]; P_new[ter_max]=work[1]; S_new[ter_mn-1]=work2[]; P_new[ter_mn-1]=work2[1]; 19
else{ MPI_Irecv(work, 1, param_rowtype, myrank+1, MPI_ANY_TAG, MPI_COMM_WORLD, &request_arr[]); MPI_Irecv(work2, 1, param_rowtype, myrank-1, MPI_ANY_TAG, MPI_COMM_WORLD, &request_arr[1]); MPI_Watall(2,request_arr,status_arr); S_new[ter_max]=work[]; P_new[ter_max]=work[1]; S_new[ter_mn-1]=work2[]; P_new[ter_mn-1]=work2[1]; work[]=s_new[ter_mn]; work[1]=p_new[ter_mn]; MPI_Isend(work,/*msg buf*/ 1,/*one data tem*/ param_rowtype,/*type*/ myrank-1,/*dest prc*/ 1, /* msg tag*/ MPI_COMM_WORLD, &request_arr[]); /*def comm*/ work2[]=s_new[ter_max-1]; work2[1]=p_new[ter_max-1]; MPI_Isend(work2,/*msg buf*/ 1,/*one data tem*/ param_rowtype,/*type*/ myrank+1,/*dest prc*/ 1, /* msg tag*/ MPI_COMM_WORLD,&request_arr[1]); /*def comm*/ MPI_Watall(2,request_arr,status_arr); Tmp1=S_new; Tmp2=P_new; S_new=S; P_new=P; S=Tmp1; P=Tmp2; prntf("hello world!\n %e",i); prntf("analtns atsakymas pre mazu koncentracu:%e \n",(ne*f*d*(s/d)*(1-1/(cosh(d*sqrt(vmax/(km*d))))))); prntf("analtns atsakymas pre ddelu koncentracu:%e \n",(ne*f*vmax*d)/2); tme(&tmer2); prntf("lakas: %f", dfftme (tmer2,tmer1)); MPI_Fnalze(); return ; 2
OpenMPI paledmo skrptas #!/bn/sh #SBATCH -p short #SBATCH -C beta #SBATCH -n24 mpcc -o man man.c echo 14 mprun -np 14 man 21