Advertisement
Guest User

Untitled

a guest
Dec 15th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.67 KB | None | 0 0
  1. /*
  2. Задача №0 (Сумма элементов массива).
  3. 1. Вывести на экран в столбик суммы, посчитанные процессами.
  4. 2. Вывести на экран сумму всех элементов, посчитанную последовательно.
  5. Сравнить её с суммой, полученной параллельно.
  6. */
  7.  
  8. #include <mpi.h>
  9. #include <assert.h>
  10. #include <stdint.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14.  
  15. ///////////////////////////////
  16. // Запись частичных сумм
  17.  
  18. void write_results(int id, uint64_t result) {
  19. printf("Частичная сумма процесса №%d равна %ld\n", id, result);
  20. }
  21.  
  22. //////////////////////////////
  23. // MAIN
  24.  
  25. int main (int argc, char** argv) {
  26.  
  27. const uint32_t N = atoi(argv[1]); // размер массива
  28.  
  29. // Инициализация MPI
  30. if (MPI_Init (NULL, NULL) != MPI_SUCCESS) {
  31. perror("Ошибка инициализации MPI ");
  32. return 1;
  33. }
  34.  
  35. int world_size, world_id;
  36. MPI_Comm_size(MPI_COMM_WORLD, &world_size); // кол-во процессов
  37. MPI_Comm_rank(MPI_COMM_WORLD, &world_id); // локальный id
  38.  
  39. // Информация о разделении массива
  40. const uint32_t num_workers = world_size - 1; // кол-во "работников"
  41. const uint32_t num_for_main = (num_workers == 0) ?
  42. 0 : N % num_workers; // избыток посчитает "основной"
  43. const uint32_t num_elem_per_worker = (num_workers == 0) ?
  44. 0 : (N - num_for_main) / num_workers;
  45. uint64_t loc_sum = 0; // частичная сумма, локальная
  46.  
  47. // "Основной" процесс
  48. if (world_id == 0) {
  49. uint32_t arr[N];
  50. uint64_t check_summ = 0;
  51.  
  52. // заполнит массив, посчитает сумму для проверки
  53. for (int i = 0; i < N; i ++) {
  54. arr[i] = i;
  55. check_summ += arr[i];
  56. }
  57.  
  58.  
  59. // рассылает подмассивы
  60. for (int i = 0; i < num_workers; i ++) {
  61. if (MPI_Send(
  62. arr + i * (num_elem_per_worker), // arr + offset
  63. num_elem_per_worker, // кол-во элементов на "работника"
  64. MPI_UNSIGNED, // тип
  65. i + 1, // кому шлём
  66. 0, // тэг
  67. MPI_COMM_WORLD // группа
  68. ) != MPI_SUCCESS) {
  69. perror("Ошибка передачи работнику\n");
  70. }
  71. }
  72.  
  73. // считает свою часть
  74. for (int i = num_workers * num_elem_per_worker; i < N; i ++) {
  75. loc_sum += arr[i];
  76. }
  77. write_results(world_id, loc_sum);
  78.  
  79. // принимает частичные суммы "работников"
  80. uint64_t worker_loc_sum = 0;
  81. for (int i = 0; i < num_workers; i ++) {
  82. if (MPI_Recv(
  83. &worker_loc_sum, // куда пишем
  84. 1, // кол-во элементов
  85. MPI_LONG, // тип
  86. i + 1, // от кого
  87. 0, // тэг?
  88. MPI_COMM_WORLD, // группа
  89. MPI_STATUS_IGNORE // флаг
  90. ) != MPI_SUCCESS) {
  91. perror("Ошибка получения от работника\n");
  92. }
  93. write_results(i + 1, worker_loc_sum);
  94. // к своей сумме прибавляет полученную
  95. loc_sum += worker_loc_sum;
  96. }
  97.  
  98. // сверяется с корректной суммой
  99. printf("Верная сумма равна %ld, мы получили %ld\n", check_summ, loc_sum );
  100. loc_sum == check_summ ? printf("Success!!!!\n") : printf("epic fail\n");
  101. }
  102. // Процессы для подчета частичных сумм, "работники"
  103. else {
  104. // принимают сообщение от "основного"
  105. uint32_t worker_arr[num_elem_per_worker];
  106. if (MPI_Recv(
  107. worker_arr, // куда пишем
  108. num_elem_per_worker, // кол-во элементов
  109. MPI_UNSIGNED, // тип
  110. 0, // от кого
  111. 0, // тэг?
  112. MPI_COMM_WORLD, // группа
  113. MPI_STATUS_IGNORE // флаг
  114. ) != MPI_SUCCESS) {
  115. perror("Ошибка получения от основного\n");
  116. return 1;
  117. }
  118.  
  119. // считают свою частичную сумму
  120. for (int i = 0; i < num_elem_per_worker; i ++) {
  121. loc_sum += worker_arr[i];
  122. }
  123.  
  124. // отправляют её "основному"
  125. if (MPI_Send(
  126. &loc_sum, // что отправляем?
  127. 1, // кол-во элементов
  128. MPI_LONG, // тип
  129. 0, // кому
  130. 0, // тэг
  131. MPI_COMM_WORLD // группа
  132. ) != MPI_SUCCESS) {
  133. perror("Ошибка передачи основному\n");
  134. }
  135. }
  136. MPI_Finalize();
  137. return 0;
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement