Advertisement
Sailein

MPI primal

Dec 14th, 2018
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.20 KB | None | 0 0
  1. #include "pch.h"
  2. #include "mpi.h"
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <math.h>
  6. #include <time.h>
  7. #include <conio.h>
  8. #include <string.h>
  9.  
  10. int main(int argc, char* argv[])
  11. {
  12.     int size;
  13.     int *chisla;
  14.     int *chisla_buf = NULL;
  15.     int myrank, num_proc;
  16.     int TAG = 0;
  17.     char processor_name[MPI_MAX_PROCESSOR_NAME];
  18.     int namelen = MPI_MAX_PROCESSOR_NAME;
  19.     double startwtime, endwtime;
  20.     FILE *prchisla;
  21.     int fl;
  22.     char ch[50];
  23.     int porog, diapason, ost, start, end;
  24.     int i, j, flag;
  25.     int buf, kol;
  26.     MPI_Init(&argc, &argv); // инициализируем работу программы MPI
  27.     // Инициализируем счетчик отсчета времени работы программы
  28.     // Определяем номер процессора
  29.     MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  30.     // Определяем число процессоров
  31.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  32.     // Определяем имя компьютера на котором запущен процесс
  33.     MPI_Get_processor_name(processor_name, &namelen);
  34.     // Выводим полученную информацию на экран
  35.     fprintf(stderr, "\nProcess %d started working at machine %s\n", myrank, processor_name);
  36.     fflush(stdout);
  37.     if (myrank == 0) // усли это главный процессб то
  38.     {
  39.         // открываем на запись файл, в который будем записывать найденные простые числа
  40.         prchisla = fopen("primes.txt", "w");
  41.         // Вводим число в пределах кторого необходимо будет найти все простые числа
  42.         printf("\nEnter prime numbers seeking range:");
  43.         fflush(stdout);
  44.             scanf("%s", &ch); // Считываем вводимое число посимвольно
  45.         porog = atoi(ch); // преобразуем ввседенное число
  46.         startwtime = MPI_Wtime(); // Инициализируем счетчик отсчета времени
  47.         diapason = porog / size; // Количество чисел для анализа каждым поцессом
  48.         ost = porog - diapason * size; // Остаток от деления
  49.         // Главный процесс посылает остальным процессам диапазон анализа
  50.         MPI_Bcast(&diapason, 1, MPI_INT, 0, MPI_COMM_WORLD);
  51.         MPI_Barrier(MPI_COMM_WORLD);
  52.         // Ожидаем пока все процессы получат данные
  53.         start = (size - 1) * diapason + 2; // Определяем начальное число анализа
  54.         end = (size * diapason) + ost; // Определяем конечное число анализа
  55.         chisla = (int*)malloc((diapason + ost) * sizeof(int));
  56.         // Инициализируем массивы для хранения результатов анализа
  57.         chisla_buf = (int*)malloc(diapason * sizeof(int));
  58.         for (i = 0; i < diapason; i++)
  59.             chisla[i] = 0; // Обнуляем инициализированные массивы
  60.         for (i = 0; i < diapason; i++)
  61.             chisla_buf[i] = 0;
  62.         kol = 0;
  63.         if (start == 2) // Если начальное число анализа равно 2,
  64.         {
  65.             chisla[kol] = 2; // то заносим его в массив результата
  66.             kol++;
  67.             start = start + 1;
  68.         } //и переходим к дальнейшему анализу
  69.         for (i = start; i <= end; i++) // Поочередно берем каждый из элементов
  70.         {
  71.             j = 1;
  72.             flag = 1; // Устанавливаем флаг в 1
  73.             do
  74.             {
  75.                 j++;
  76.                 // Начинаем делить на 2 все возможные делители
  77.                 // Первый раз j = 2.
  78.                 buf = i / j;
  79.                 if ((buf * j) == i) // Если число поделилось нацело, то оно не является простым
  80.                     flag = 0;
  81.             } // Анализ продолжается пока не будут проверены все делители и флаг не будет равен 1
  82.             while ((j < (i - 1)) && (flag == 1));
  83.             if (flag == 1) // Если флаг остался равен 1
  84.             {
  85.                 chisla[kol] = j + 1; // то это простое число и мы заносим его в массив
  86.                 kol++;
  87.             }
  88.         }
  89.         if (size > 1) // Если в вычислениях учавствует более 1 процесса
  90.         {
  91.             for (j = 1; j < size; j++)
  92.             { // то принимаем данные от каждого из них
  93.                 num_proc = j;
  94.                 MPI_Recv(chisla_buf, diapason, MPI_INT, num_proc, TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  95.                 i = 0;
  96.                 while ((i < diapason) && (chisla_buf[i] != 0))
  97.                 {
  98.                     if (chisla_buf[i] != 0) //Заносим принятые данные в выходной файл
  99.                     {
  100.                         fprintf(prchisla, "%d \n", chisla_buf[i]);
  101.                         fflush(prchisla);
  102.                     }
  103.                     i++;
  104.                 }
  105.             }
  106.         }
  107.         i = 0; // После этого заносим в выходной файл данные, полученные главным процессом
  108.         while ((i < (diapason + ost)) && (chisla[i] != 0))
  109.         {
  110.             if (chisla[i] != 0)
  111.             {
  112.                 fprintf(prchisla, "%d \n", chisla[i]);
  113.                 fflush(prchisla);
  114.             }
  115.             i++;
  116.         }
  117.         MPI_Barrier(MPI_COMM_WORLD); // ожидаем пока все процессы вызовут эту функцию
  118.         endwtime = MPI_Wtime();
  119.         printf("\n wall clock time = %f\n", endwtime - startwtime); // Выводим на экран время работы программы.
  120.         fflush(stdout);
  121.         printf("\nAnalysis complete!\n");
  122.         fflush(stdout);
  123.         free(chisla); // освобождаем динамическую память
  124.         free(chisla_buf);
  125.         fclose(prchisla);
  126.     }
  127.     else // Если это не главный процесс, то принимаем данные от главного процесса
  128.     {
  129.         MPI_Bcast(&diapason, 1, MPI_INT, 0, MPI_COMM_WORLD);
  130.         printf("\n Process %d received data from manager process, diapason = %d\n", myrank, diapason);
  131.         fflush(stdout);
  132.         MPI_Barrier(MPI_COMM_WORLD); // Ожидаем пока все процессы вызовут эту функцию
  133.         start = (myrank - 1) * diapason + 2; // Определяем начальное число анализа
  134.         end = (myrank * diapason) + 1; // Определяем конечное число анализа
  135.         chisla = (int*)malloc(diapason * sizeof(int)); // Инициализируем массив для хранения резудьтатов анализа
  136.         for (i = 0; i < diapason; i++)
  137.             chisla[i] = 0; // Обнуляем инициализированные массивы
  138.         kol = 0;
  139.         if (start == 2) // Если начальное число анализа равно 2,
  140.         {
  141.             chisla[kol] = 2; // то заносим его в массив результата
  142.             kol++; // и переходим к дальнейшему анализу
  143.             start++;
  144.         }
  145.         for (i = start; i <= end; i++) // поочередно берем каждый из элементов
  146.         {
  147.             j = 1;
  148.             flag = 1; // Устанавливаем флаг в 1
  149.             do
  150.             {
  151.                 j++; // Начинаем делить на всевозможные делители. Первый раз j = 2.
  152.                 buf = i / j;
  153.                 if ((buf * j) == i) // Если чисо поделилось нацело, то оно НЕ является простым
  154.                     flag = 0; // и поэтому флаг устанавливается в 0
  155.             }
  156.             while ((j < (i - 1)) && (flag == 1)); // Анализ продолжается пока не будут проверены все делители и флаг не будет равен 1
  157.             if (flag == 1) // Если флаг остался равен 1, то это простое число и мы заносим его в массив
  158.             {
  159.                 chisla[kol] = j + 1;
  160.                 kol++;
  161.             }
  162.         }
  163.         MPI_Send(chisla, diapason, MPI_INT, 0, TAG, MPI_COMM_WORLD); // Передаем массив с результатами главному процессору
  164.         MPI_Barrier(MPI_COMM_WORLD); // Ожмдаем пока все процессы вызовут эту функцию
  165.         free(chisla_buf); // освобождаем динамическую память
  166.     }
  167.     MPI_Finalize(); // Завершаем работу программы MPI
  168.     return 0;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement