Advertisement
Guest User

I HATE MPI

a guest
May 26th, 2016
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.06 KB | None | 0 0
  1. //35 Число называется циркулярно простым, если любая круговая перестановка его цифр
  2. //есть простое число (например – 197 или 31 или 17). Найти количество циркулярно простых чисел в диапазоне от N до M
  3.  
  4. #define _CRT_SECURE_NO_WARNINGS
  5. #include <cstdlib>
  6. #include <ctime>
  7. #include <mpi.h>
  8. #include <iostream>
  9. #include <stdio.h>
  10. #include <cmath>
  11. #include <vector>
  12. #define TAG_SUCCESS 97
  13. #define TAG_CUR 96
  14. #define TAG_PREV 95
  15. #define TAG_INITIATIVE 94
  16. #define TAG_STAND 93
  17. using namespace std;
  18. typedef unsigned long long big;
  19.  
  20.  
  21. #define PRINTS(x) fprintf(stdout, x); fflush(stdout);
  22. #define PRINT(x, y) fprintf(stdout, x, y); fflush(stdout);
  23.  
  24. int cmpfunc(const void * a, const void * b)
  25. {
  26.     return (*(big*)a - *(big*)b);
  27. }
  28.  
  29. //функция проверяет, четное ли число
  30. big isEven(big number)
  31. {
  32.     if (number % 2 == 0) return number / 2;
  33.     else return 0;
  34. }
  35. //быстрое умножение по модулю
  36. big mul(big a, big b, big m)
  37. {
  38.     if (b == 1) return a;
  39.     if (b % 2 == 0)
  40.     {
  41.         big t = mul(a, b / 2, m);
  42.         return (2 * t) % m;
  43.     }
  44.     return (mul(a, b - 1, m) + a) % m;
  45. }
  46. //быстрое возведение в степень по модулю
  47. big pows(big a, big b, big m)
  48. {
  49.     if (b == 0) return 1;
  50.     if (b % 2 == 0)
  51.     {
  52.         big t = pows(a, b / 2, m);
  53.         return mul(t, t, m) % m;
  54.     }
  55.     return (mul(pows(a, b - 1, m), a, m)) % m;
  56. }
  57. //поиск наибольшего общего делителя
  58. big gcd(big a, big b)
  59. {
  60.     if (b == 0) return a;
  61.     return gcd(b, a%b);
  62. }
  63. //вероятностный тест Ферма
  64. bool ferma(big x, int rank, int total)
  65. {
  66.     if (rank == 0)
  67.         MPI_Bcast(&rank, 1, MPI_UNSIGNED_LONG_LONG, 0, MPI_COMM_WORLD);
  68.  
  69.     if (x == 2) return true;
  70.     srand(time(NULL));
  71.     int res = 0;
  72.     big a;
  73.     for (int i = rank; i < 100; i+=total)
  74.     {
  75.         a = (rand() % (x - 2)) + 2;
  76.         if (gcd(a, x) != 1) res++;
  77.         if (pows(a, x - 1, x) != 1) res++;
  78.     }
  79.  
  80.     if (rank == 0)
  81.     {
  82.         int reduced = 0;
  83.         MPI_Reduce(&res, &reduced, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
  84.  
  85.         if (reduced == 0)   return true;
  86.         else return false;
  87.     }
  88.  
  89.     if (res == 0)   return true;
  90.     else return false;
  91. }
  92. //////////////////////////////////////////////////////////////////
  93. int main(int argc, char* argv[])
  94. {
  95.     int myid;
  96.     int numprocs;
  97.     big n;
  98.     auto startwtime = 0.0;
  99.     auto endwtime = 0.0;
  100.     MPI_Init(&argc, &argv);
  101.     MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  102.     MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  103.     if (myid == 0)
  104.     {
  105.        
  106.         cout << "vvedite chislo\nhint: try 8789451874165\n";
  107.         cin >>n;
  108.         startwtime = MPI_Wtime();
  109.     }
  110.    
  111.     MPI_Bcast(&n, 1, MPI_UNSIGNED_LONG_LONG, 0, MPI_COMM_WORLD);
  112.     vector<big> nums;
  113.     auto start_n = n;
  114.     big k = sqrt(n);
  115.  
  116.     for (big i = 2 + myid; i <= k; i+=numprocs) {
  117.         while (n % i == 0) {
  118.             PRINT("%llu\n", i);
  119.             nums.push_back(i);
  120.             n /= i;
  121.         }
  122.     }
  123.  
  124.     if (n != 1 && n!=start_n) {
  125.         PRINT("%llu\n", n);
  126.         nums.push_back(n);
  127.     }
  128.  
  129.     int local_nums = nums.size();
  130.     int total_nums;
  131.     MPI_Allreduce(&local_nums, &total_nums, 1, MPI_UNSIGNED_LONG_LONG, MPI_SUM,  MPI_COMM_WORLD);
  132.     //vector<big> all_nums(total_nums);
  133.     big* all_nums = new big[total_nums];
  134.     while (nums.size() != total_nums) nums.push_back(0);
  135.     if (myid == 0) PRINT("Total nums : %d\n", total_nums);
  136.  
  137.     MPI_Gather(nums.data(), total_nums, MPI_UNSIGNED_LONG_LONG, all_nums, total_nums, MPI_UNSIGNED_LONG_LONG, 0, MPI_COMM_WORLD);
  138.     if (myid == 0)
  139.     {
  140.         qsort(all_nums, total_nums*numprocs, sizeof(big), cmpfunc);
  141.         for (int i = 0; i < total_nums*numprocs; i++)
  142.         {
  143.             cout << all_nums[i] << ", ";
  144.         }
  145.         PRINTS("\nFINAL NUMBERS\n");
  146.         big a = 1;
  147.         for (int i = 0; i < total_nums*numprocs; i++)
  148.         {
  149.             if (all_nums[i] != 0)
  150.             {
  151.                 a *= all_nums[i];
  152.                 if (a <= n) { PRINT("%llu\n", all_nums[i]); }
  153.                 else break;
  154.             }
  155.         }
  156.         endwtime = MPI_Wtime();
  157.         clog << endl << "Total: " << (endwtime - startwtime) * 1000 << " ms" << endl;
  158.     }
  159.     delete all_nums;
  160.     MPI_Finalize();
  161.     //system("PAUSE");
  162.     return 0;
  163. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement