Advertisement
Guest User

Untitled

a guest
Nov 20th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.31 KB | None | 0 0
  1. L4 - difuzia 1 la toti pe hupercub
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include"mpi.h"
  5.  
  6. int mylogaritm(int nr) {
  7. int count = 0;
  8. while ((nr & 0x1) != 1) {
  9. nr = nr >> 1;
  10. count++;
  11. }
  12. if (nr == 1) {
  13. return count;
  14. } else {
  15. return -1;
  16. }
  17. }
  18.  
  19. int main(int argc, char ** argv) {
  20. int myrank, count;
  21. char M[10] = "mesaj";
  22. int d;
  23. int id;
  24. int s = 0;
  25. int id_virtual;
  26. int masca;
  27. int i;
  28. int destinatie_virtuala, sursa_virtuala;
  29. char primit[10];
  30. MPI_Status status;
  31.  
  32. MPI_Init(&argc, &argv);
  33. MPI_Comm_size(MPI_COMM_WORLD, &count);
  34. MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  35.  
  36. d = mylogaritm(count);
  37.  
  38. if (d == -1) {
  39. MPI_Finalize();
  40. return 0;
  41. }
  42.  
  43. id = myrank;
  44. id_virtual = id ^ s;
  45. masca = (1 << d) - 1;
  46. for (i = d - 1; i >= 0; i--) {
  47. masca = masca ^ (1 << i);
  48. if ((id_virtual & masca) == 0) {
  49. if ((id_virtual & (1 << i)) == 0) {
  50. destinatie_virtuala = id_virtual ^ (1 << i);
  51. //printf("%d trimit catre %d\n", myrank, destinatie_virtuala ^ s);
  52. MPI_Send(M, strlen(M), MPI_CHAR, destinatie_virtuala ^ s, 1,
  53. MPI_COMM_WORLD);
  54. } else {
  55. sursa_virtuala = id_virtual ^ (1 << i);
  56. MPI_Recv(M, 20, MPI_CHAR, sursa_virtuala ^ s, 1, MPI_COMM_WORLD,
  57. &status);
  58. printf("eu sunt %d si am primit de la %d\n", id_virtual,
  59. sursa_virtuala);
  60. }
  61. }
  62. }
  63. MPI_Finalize();
  64. return 0;
  65. }
  66.  
  67.  
  68. L5 - Difuzia 1 la toti pe un arbore
  69. #include <stdio.h>
  70. #include <stdlib.h>
  71. #include <string.h>
  72. #include <mpi/mpi.h>
  73.  
  74. #define ROOT 4 // nodul radacina
  75.  
  76. int main(int argc, char* argv[])
  77. {
  78. int rank; // rank-ul procesului curent
  79. int p; // numarul de procese
  80. int sursa; // rank-ul procesului sender
  81. int destinatie; // rank-ul procesului reciever
  82. int eticheta = 99; // eticheta pentru mesaje
  83. char M[100] = "Hello world!"; // sirul de caractere ce alcatuiesc mesajul
  84. MPI_Status status; // starea de return pentru operatia de recieve
  85. MPI_Comm graph; // comunicatorul pentru topologia de tip graf
  86.  
  87. int index[] = {1, 2, 5, 7, 10, 11, 14, 15, 16}; // index[0] = grad[0]; index[i] = index[i - 1] + grad[i]
  88. int nrOfNodes = 9;
  89. /*
  90. Listele de adiacenta:
  91. 0 -> 4
  92. 1 -> 6
  93. 2 -> 4, 7, 8
  94. 3 -> 4, 6
  95. 4 -> 0, 2, 3
  96. 5 -> 6
  97. 6 -> 1, 3, 5
  98. 7 -> 2
  99. 8 -> 2
  100. */
  101. int edges[] = {4, 6, 4, 7, 8, 4, 6, 0, 2, 3, 6, 1, 3, 5, 2, 2}; // vecinii incep din stanga si se termina in dreapta - 1
  102.  
  103. MPI_Init(&argc, &argv);
  104. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  105. MPI_Comm_size(MPI_COMM_WORLD, &p);
  106. MPI_Graph_create(MPI_COMM_WORLD, nrOfNodes, index, edges, 0, &graph);
  107. int ncount;
  108. MPI_Graph_neighbors_count(graph, rank, &ncount);
  109. int* neighbors = (int*) malloc(ncount * sizeof(int));
  110. if (!neighbors)
  111. {
  112. fprintf(stderr, "Eroare la alocare!\n");
  113. MPI_Comm_free(&graph);
  114. MPI_Finalize();
  115. exit(EXIT_FAILURE);
  116. }
  117. MPI_Graph_neighbors(graph, rank, ncount, neighbors);
  118.  
  119. if (rank == ROOT) // pentru nodul radacina
  120. {
  121. int i;
  122. // trimitem mesajul catre copii
  123. for (i = 0; i < ncount; ++i) // parcurgem lista de vecini a nodului radacina
  124. {
  125. destinatie = neighbors[i];
  126. MPI_Send(M, (int)(strlen(M) + 1), MPI_CHAR, destinatie, eticheta, graph);
  127. printf("[Radacina %d] Am trimis mesajul \"%s\" catre destinatia %d.\n", rank, M, destinatie);
  128. }
  129. }
  130. else
  131. {
  132. MPI_Recv(M, 100, MPI_CHAR, MPI_ANY_SOURCE, eticheta, graph, &status);
  133. if (ncount > 1) // daca nodul nu este frunza (este intermediar)
  134. {
  135. int i;
  136. // trimitem mesajul catre copii
  137. for (i = 0; i < ncount; ++i)
  138. {
  139. destinatie = neighbors[i];
  140. if (destinatie != status.MPI_SOURCE) // ne asiguram ca nu trimitem nodului parinte
  141. {
  142. MPI_Send(M, (int)(strlen(M) + 1), MPI_CHAR, destinatie, eticheta, graph);
  143. printf("[Nod %d] Am trimis mesajul \"%s\" catre destinatia %d.\n", rank, M, destinatie);
  144. }
  145. }
  146. }
  147. }
  148.  
  149. // dealocam vectorul de vecini
  150. if (neighbors)
  151. {
  152. free(neighbors);
  153. }
  154.  
  155. // free la topologia de tip graf
  156. MPI_Comm_free(&graph);
  157.  
  158. // oprim MPI
  159. MPI_Finalize();
  160.  
  161. return 0;
  162. }
  163.  
  164.  
  165. L5 - Difuzia toti la 1 pe un arbore
  166. #include <stdio.h>
  167. #include <stdlib.h>
  168. #include <string.h>
  169. #include <mpi/mpi.h>
  170.  
  171. #define ROOT 4 // nodul radacina
  172.  
  173. int main(int argc, char* argv[])
  174. {
  175. int rank; // rank-ul procesului curent
  176. int p; // numarul de procese
  177. int sursa; // rank-ul procesului sender
  178. int destinatie; // rank-ul procesului reciever
  179. int eticheta = 99; // eticheta pentru mesaje
  180. int M; // sirul de caractere ce alcatuiesc mesajul
  181. int calculMesaj; // calculul facut de nodul care primeste mesaje de la copii
  182. int sumaVecini; // suma rank-urilor tuturor vecinilor nodului curent
  183. MPI_Status status; // starea de return pentru operatia de recieve
  184. MPI_Comm graph; // comunicatorul pentru topologia de tip graf
  185.  
  186. int index[] = {1, 2, 5, 7, 10, 11, 14, 15, 16}; // index[0] = grad[0]; index[i] = index[i - 1] + grad[i]
  187. int nrOfNodes = 9;
  188. /*
  189. Listele de adiacenta:
  190. 0 -> 4
  191. 1 -> 6
  192. 2 -> 4, 7, 8
  193. 3 -> 4, 6
  194. 4 -> 0, 2, 3
  195. 5 -> 6
  196. 6 -> 1, 3, 5
  197. 7 -> 2
  198. 8 -> 2
  199. */
  200. int edges[] = {4, 6, 4, 7, 8, 4, 6, 0, 2, 3, 6, 1, 3, 5, 2, 2}; // vecinii incep din stanga si se termina in dreapta - 1
  201. // lista de muchii este rezultatul concatenarii listelor de adiacenta
  202.  
  203. // pornire MPI
  204. MPI_Init(&argc, &argv);
  205.  
  206. // aflam rank-ul pentru procesul curent
  207. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  208.  
  209. // aflam numarul de procese
  210. MPI_Comm_size(MPI_COMM_WORLD, &p);
  211.  
  212. // cream topologia de tip graf
  213. MPI_Graph_create(MPI_COMM_WORLD, nrOfNodes, index, edges, 0, &graph);
  214.  
  215. // numarul de vecini
  216. int ncount;
  217. MPI_Graph_neighbors_count(graph, rank, &ncount);
  218.  
  219. // preluam vecinii
  220. int* neighbors = (int*) malloc(ncount * sizeof(int));
  221. if (!neighbors)
  222. {
  223. fprintf(stderr, "Eroare la alocare!\n");
  224. MPI_Comm_free(&graph);
  225. MPI_Finalize();
  226. exit(EXIT_FAILURE);
  227. }
  228. MPI_Graph_neighbors(graph, rank, ncount, neighbors);
  229.  
  230. // calculam suma rank-urilor vecinilor
  231. int i;
  232. sumaVecini = 0;
  233. for (i = 0; i < ncount; ++i)
  234. {
  235. sumaVecini += neighbors[i];
  236. }
  237.  
  238. if (rank == ROOT) // pentru nodul radacina
  239. {
  240. // algoritmul 5
  241. // asteptam primirea tuturor mesajelor de la copii
  242. calculMesaj = 0;
  243. for (i = 0; i < ncount; ++i)
  244. {
  245. sursa = neighbors[i];
  246. MPI_Recv(&M, 1, MPI_INT, sursa, eticheta, graph, &status);
  247. printf("[Radacina %d] Am primit mesajul \"%d\" de la sursa %d.\n", rank, M, sursa);
  248.  
  249. // adunam ID-ul primit in mesaj la suma curenta
  250. calculMesaj += M;
  251. }
  252. printf("[Radacina %d] Suma de ID-uri calculata: %d.\n", rank, calculMesaj);
  253. }
  254. else
  255. {
  256. if (ncount == 1) // daca nodul este frunza
  257. {
  258. // trimitem mesajul catre parinte
  259. destinatie = neighbors[0]; // parintele este singurul vecin al frunzei
  260. MPI_Send(&rank, 1, MPI_INT, destinatie, eticheta, graph);
  261. printf("[Nod %d] Am trimis mesajul \"%d\" catre destinatia %d.\n", rank, rank, destinatie);
  262. }
  263. else // daca nodul este intermediar
  264. {
  265. // algoritmul 4
  266. // asteptam primirea tuturor mesajelor de la copii
  267. calculMesaj = 0;
  268. for (i = 0; i < ncount - 1; ++i)
  269. {
  270. sursa = neighbors[i];
  271. MPI_Recv(&M, 1, MPI_INT, MPI_ANY_SOURCE, eticheta, graph, &status);
  272. printf("[Nod %d] Am primit mesajul \"%d\" de la sursa %d.\n", rank, M, sursa);
  273. sumaVecini -= status.MPI_SOURCE; // scadem rank-ul nodului de la care am primit
  274.  
  275. // adunam ID-ul primit in mesaj la suma curenta
  276. calculMesaj += M;
  277. }
  278.  
  279. // aici, in variabila "sumaVecini" va ramane rank-ul nodului parinte
  280. destinatie = sumaVecini;
  281.  
  282. // trimitem calculul facut (suma rank-urilor nodurilor de la care am primit) catre nodul parinte
  283. // plus rank-ul propriu
  284. calculMesaj += rank;
  285. MPI_Send(&calculMesaj, 1, MPI_INT, destinatie, eticheta, graph);
  286. printf("[Nod %d] Am trimis mesajul \"%d\" catre destinatia %d.\n", rank, calculMesaj, destinatie);
  287. }
  288. }
  289.  
  290. // dealocam vectorul de vecini
  291. if (neighbors)
  292. {
  293. free(neighbors);
  294. }
  295.  
  296. // free la topologia de tip graf
  297. MPI_Comm_free(&graph);
  298.  
  299. // oprim MPI
  300. MPI_Finalize();
  301.  
  302. return 0;
  303. }
  304.  
  305. L6 - Coprimare prefixe - OMP
  306. #include <omp.h>
  307. #include <stdio.h>
  308. #include <stdlib.h>
  309.  
  310. void comprimare(int A[], int m)
  311. {
  312. int k, j;
  313. int k1;
  314. int k2;
  315.  
  316. for (k = m - 1; k >= 0; --k)
  317. {
  318. k1 = 1 << k;
  319. k2 = 1 << (k + 1);
  320.  
  321. #pragma omp parallel for private(j) num_threads(k1)
  322. for (j = k1; j <= k2 - 1; ++j)
  323. {
  324. A[j] = A[2 * j] + A[2 * j + 1];
  325. }
  326. }
  327. }
  328.  
  329. void calculPrefixe(int A[], int B[], int m)
  330. {
  331.  
  332. B[1] = A[1];
  333. int k,j;
  334. int k1;
  335. int k2;
  336.  
  337. for (k = 1; k <= m; ++k)
  338. {
  339. k1 = 1 << k;
  340. k2 = 1 << (k + 1);
  341. #pragma omp parallel for private(j) num_threads(k1)
  342. for (j = k1; j <= k2 - 1; ++j)
  343. {
  344. if (j % 2 == 1)
  345. {
  346. B[j] = B[(j - 1) / 2];
  347. }
  348. else
  349. {
  350. B[j] = B[j / 2] - A[j + 1];
  351. }
  352. }
  353. }
  354. }
  355.  
  356. int main() {
  357. int m = 3;
  358. int i;
  359. int dim = 16;
  360. int A[16]= {0,0,0,0,0,0,0,0,3,2,1,6,5,4,2,9};
  361. int B[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  362.  
  363. comprimare(A,m);
  364. printf("A = ");
  365. for (i = 0; i < dim; ++i)
  366. {
  367. printf("%d ", A[i]);
  368. }
  369. calculPrefixe(A, B,m);
  370. printf("\nB = ");
  371. for (i = 0; i < dim; ++i)
  372. {
  373. printf("%d ", B[i]);
  374. }
  375. return 0;
  376. }
  377.  
  378. L6 Comprimare_prefixe MPI
  379. #include <stdio.h>
  380. #include <stdlib.h>
  381. #include "mpi.h"
  382.  
  383. #define NP 16 // numarul de procese este 2 * n
  384. #define ROOT 1 // nodul radacina
  385.  
  386.  
  387. int main(int argc, char *argv[]) {
  388. int A[16] = { 0,0,0,0,0,0,0,0,3,2,1,6,5,4,2,9 };
  389. int B[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  390.  
  391. int rank; // rank-ul procesului curent
  392. int np; // numarul de procese = dimensiunea tabloului A
  393. MPI_Status status; // starea operatiei de recieve
  394. int sursaStanga, sursaDreapta; // rank-urile proceselor sender (copiii)
  395. int destinatieStanga, destinatieDreapta; // rank-urile proceselor reciever (copiii)
  396. int sursa; // rank-ul procesului sender
  397. int destinatie; // rank-ul procesului reciever
  398. int eticheta = 99; // eticheta pentru mesaje
  399. int valoarePrimita; // ce am primit de la procesul parinte
  400. int valoarePrimitaStanga, valoarePrimitaDreapta; // ce am primit de la procesele fiu
  401. int rezultatCalcul; // rezultatul calculului efectuat de nodul curent
  402. int val; // valoarea corespunzatoare procesului cu rank-ul curent
  403. MPI_Init(&argc, &argv);
  404. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  405. MPI_Comm_size(MPI_COMM_WORLD, &np);
  406. MPI_Scatter(A, 1, MPI_INT, &val, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
  407.  
  408. if (rank >= np / 2) // pentru frunze
  409. {
  410. destinatie = rank / 2;
  411. MPI_Send(&val, 1, MPI_INT, destinatie, eticheta, MPI_COMM_WORLD);
  412. printf("[Frunza %d] Am trimis mesajul \"%d\" catre nodul parinte %d.\n", rank, val, destinatie);
  413. }
  414. else if (rank != 0) // pentru nodurile intermediare (fara procesul 0, care nu este folosit!)
  415. {
  416. sursaStanga = 2 * rank; // copilul stang
  417. sursaDreapta = 2 * rank + 1; // copilul drept
  418.  
  419. MPI_Recv(&valoarePrimitaStanga, 1, MPI_INT, sursaStanga, eticheta, MPI_COMM_WORLD, &status);
  420. printf("[Nod %d] Am primit mesajul \"%d\" de la copilul stang %d.\n", rank, valoarePrimitaStanga, sursaStanga);
  421.  
  422. MPI_Recv(&valoarePrimitaDreapta, 1, MPI_INT, sursaDreapta, eticheta, MPI_COMM_WORLD, &status);
  423. printf("[Nod %d] Am primit mesajul \"%d\" de la copilul drept %d.\n", rank, valoarePrimitaDreapta, sursaDreapta);
  424.  
  425. rezultatCalcul = valoarePrimitaStanga + valoarePrimitaDreapta;
  426. printf("[Nod %d] Am calculat valoarea \"%d\".\n", rank, rezultatCalcul);
  427. val = rezultatCalcul;
  428.  
  429. if (rank != ROOT) // in afara de nodul radacina
  430. {
  431. destinatie = rank / 2;
  432. MPI_Send(&val, 1, MPI_INT, destinatie, eticheta, MPI_COMM_WORLD);
  433. printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul parinte %d.\n", rank, val, destinatie);
  434. }
  435. }
  436. MPI_Gather(&val, 1, MPI_INT, A, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
  437.  
  438. if (rank == ROOT) // procesul ROOT face afisarea
  439. {
  440. printf("\nTabloul, dupa comprimare:\n");
  441. for (int i = 0; i < np; i++)
  442. {
  443. printf("%d ", A[i]);
  444. }
  445. printf("\n\n");
  446.  
  447. }
  448.  
  449. if (rank == ROOT)
  450. {
  451. destinatieStanga = 2 * rank;
  452. destinatieDreapta = 2 * rank + 1;
  453.  
  454. MPI_Send(&val, 1, MPI_INT, destinatieStanga, eticheta, MPI_COMM_WORLD);
  455. printf("[Radacina %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieStanga);
  456.  
  457. MPI_Send(&val, 1, MPI_INT, destinatieDreapta, eticheta, MPI_COMM_WORLD);
  458. printf("[Radacina %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieDreapta);
  459. }
  460. else if (rank != 0) // procesul cu rank-ul 0 nu este folosit!
  461. {
  462. sursa = rank / 2;
  463. MPI_Recv(&valoarePrimita, 1, MPI_INT, sursa, eticheta, MPI_COMM_WORLD, &status);
  464. printf("[Nod %d] Am primit mesajul \"%d\" de la nodul parinte %d.\n", rank, valoarePrimita, sursa);
  465. if (rank % 2 == 0)
  466. {
  467. sursaDreapta = rank + 1;
  468. MPI_Recv(&valoarePrimitaDreapta, 1, MPI_INT, sursaDreapta, eticheta, MPI_COMM_WORLD, &status);
  469. printf("[Nod %d] Am primit mesajul \"%d\" de la nodul vecin %d.\n", rank, valoarePrimitaDreapta, sursaDreapta);
  470. val = valoarePrimita - valoarePrimitaDreapta;
  471. }
  472. else
  473. {
  474. destinatieStanga = rank - 1;
  475. MPI_Send(&val, 1, MPI_INT, destinatieStanga, eticheta, MPI_COMM_WORLD);
  476. printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul vecin %d.\n", rank, val, destinatieStanga);
  477. val = valoarePrimita;
  478. }
  479. if (rank < np / 2)
  480. {
  481. destinatieStanga = 2 * rank;
  482. destinatieDreapta = 2 * rank + 1;
  483.  
  484. MPI_Send(&val, 1, MPI_INT, destinatieStanga, eticheta, MPI_COMM_WORLD);
  485. printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieStanga);
  486.  
  487. MPI_Send(&val, 1, MPI_INT, destinatieDreapta, eticheta, MPI_COMM_WORLD);
  488. printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieDreapta);
  489. }
  490. }
  491.  
  492. MPI_Gather(&val, 1, MPI_INT, B, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
  493.  
  494. if (rank == ROOT) // procesul ROOT face afisarea, respectiv dealocarea
  495. {
  496. printf("\nTabloul, dupa calculul prefixelor:\n");
  497. for (int i = 0; i < np; i++)
  498. {
  499. printf("%d ", B[i]);
  500. }
  501. printf("\n\n");
  502.  
  503. }
  504. MPI_Finalize();
  505. return 0;
  506. }
  507.  
  508.  
  509.  
  510. L7 - Memoria partajata OMP
  511.  
  512. #include <omp.h>
  513. #include <stdio.h>
  514. #include <stdlib.h>
  515.  
  516. int main (int argc, char *argv[]) {
  517.  
  518. int A[4]={ 2, 3, 6, 8};
  519. //int A1[4];
  520. int R[8][4];
  521. int P[4];
  522. int n=4;
  523. int i,j;
  524.  
  525.  
  526.  
  527. #pragma omp parallel for private(i,j) num_threads(n)
  528.  
  529. for (i = 0; i < n; i++)
  530. {
  531. for (j = 0; j < n; j++)
  532. {
  533. if (A[i] < A[j])
  534. {
  535. R[i + n - 1][j] = 1;
  536. }
  537. else
  538. {
  539. R[i + n - 1][j] = 0;
  540. }
  541. }
  542. }
  543.  
  544.  
  545. #pragma omp parallel for private(i,j) num_threads(n)
  546. for (j = 0; j < n; j++)
  547. {
  548. for (i = n-2; i >=0; i--)
  549. {
  550. R[i][j] = R[2*i+1][j] + R[2*i+2][j];
  551. }
  552.  
  553. P[j] = R[0][j];
  554. }
  555.  
  556.  
  557. #pragma omp parallel for private(j) num_threads(n)
  558.  
  559. for (j = 0; j < n; j++) {
  560. A[P[j]] = A[j];
  561. }
  562.  
  563. for (i = 0; i < n; i++) {
  564. printf("%d ", A[i]);
  565. }
  566. return 0;
  567. }
  568.  
  569.  
  570. L7 - Memoria partajata MPI
  571.  
  572. #include <stdio.h>
  573. #include <string.h>
  574. #include "mpi.h"
  575.  
  576.  
  577. int main(int argc, char *argv[]) {
  578.  
  579. int my_rank;
  580. int p;
  581. int tag=0;
  582. int faza;
  583. int n = 8;
  584. int r, v;
  585. int A[8] = { 3, 2, 3, 8, 5, 6, 4, 1 };
  586.  
  587. MPI_Status status;
  588. MPI_Init(&argc, &argv);
  589. MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  590. MPI_Comm_size(MPI_COMM_WORLD, &p);
  591.  
  592. for (faza = 1; faza <= n; faza++)
  593. {
  594.  
  595. if (faza % 2 == 1 && (my_rank <=2*n/2-1))
  596. {
  597.  
  598. if (my_rank % 2 == 0)
  599. {
  600. r = A[my_rank];
  601. MPI_Send(&r, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD);
  602. MPI_Recv(&v, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD, &status);
  603.  
  604.  
  605. if (v < r)
  606. {
  607. A[my_rank] = v;
  608. }
  609. }
  610.  
  611. else
  612. {
  613. r = A[my_rank];
  614.  
  615. MPI_Send(&r, 1, MPI_INT, my_rank - 1, tag, MPI_COMM_WORLD);
  616. MPI_Recv(&v, 1, MPI_INT, my_rank - 1, tag, MPI_COMM_WORLD, &status);
  617.  
  618.  
  619. if (v > r)
  620. {
  621. A[my_rank] = v;
  622. }
  623. }
  624.  
  625. }
  626. if (faza % 2 == 0 && (my_rank <=(2*n-1)/2))
  627. {
  628. if (my_rank % 2 == 1)
  629. {
  630.  
  631. if (my_rank + 1 < n)
  632. {
  633. r = A[my_rank];
  634. MPI_Send(&r, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD);
  635. MPI_Recv(&v, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD,&status);
  636.  
  637. if (v < r)
  638. {
  639. A[my_rank] = v;
  640. }
  641. }
  642. }
  643. else
  644. {
  645. if (my_rank > 0)
  646. {
  647. r = A[my_rank];
  648. MPI_Send(&r, 1, MPI_INT, my_rank - 1, tag,MPI_COMM_WORLD);
  649. MPI_Recv(&v, 1, MPI_INT, my_rank - 1, tag,MPI_COMM_WORLD, &status);
  650.  
  651. if (v > r)
  652. {
  653. A[my_rank] = v;
  654. }
  655. }
  656. }
  657.  
  658. }
  659.  
  660. }
  661.  
  662. printf(" A[%d]=%d \n",my_rank,A[my_rank]);
  663.  
  664. MPI_Finalize();
  665.  
  666. return 0;
  667. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement