You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
3.6 KiB

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cmath>
  4. #include "Ttiming.h"
  5. #include <mpi.h>
  6. #include <stdio.h>
  7. using namespace std;
  8. void array_alloc(long **&arr, long arrsize)
  9. {
  10. try
  11. {
  12. arr = new long* [arrsize];
  13. arr[0] = new long [arrsize*arrsize];
  14. for(long i = 1; i < arrsize; ++i)
  15. arr[i] = arr[i-1] + arrsize;
  16. }
  17. catch (bad_alloc& ex)
  18. {
  19. cerr << "Could not allocate memory for array" << endl;
  20. exit(1);
  21. }
  22. }
  23. void vect_alloc(long *&arr, long arrsize)
  24. {
  25. try
  26. {
  27. arr = new long [arrsize];
  28. }
  29. catch (bad_alloc& ex)
  30. {
  31. cerr << "Could not allocate memory for vector" << endl;
  32. exit(1);
  33. }
  34. }
  35. void array_destroy(long **arr)
  36. {
  37. delete [] arr[0];
  38. delete [] arr;
  39. }
  40. int main(int argc, char *argv[])
  41. {
  42. long **A=NULL, **B=NULL, **C=NULL, *B_rot=NULL, *vect=NULL, *vect_c=NULL;
  43. long rozmiar=0;
  44. char *endptr;
  45. TTiming tt;
  46. long i, j;//,k;
  47. MPI::Status status;
  48. if (argc < 2)
  49. {
  50. cerr << "Usage: " << argv[0] << " <size>" << endl;
  51. exit(1);
  52. }
  53. rozmiar = strtol(argv[1], &endptr, 10);
  54. if (*endptr)
  55. {
  56. cerr << "Invalid array size format" << endl;
  57. exit(1);
  58. }
  59. if (rozmiar <= 0 || rozmiar > 2000)
  60. {
  61. cerr << "The number of matrix dimension must be in range [1,2000]" << endl;
  62. exit(1);
  63. }
  64. MPI::Init(argc, argv);
  65. int taskid = MPI::COMM_WORLD.Get_rank();
  66. int ntasks = MPI::COMM_WORLD.Get_size();
  67. printf("ntasks= %d : taskid= %d : Hello World!\n",ntasks,taskid);
  68. //alokacja macierzy
  69. array_alloc(A, rozmiar);
  70. if (taskid == 0)
  71. {
  72. array_alloc(B, rozmiar);
  73. vect_alloc(B_rot, rozmiar*rozmiar);
  74. }
  75. int porcja = (rozmiar*rozmiar)/ntasks + (rozmiar*rozmiar)%ntasks;
  76. array_alloc(C, rozmiar);
  77. vect_alloc(vect, porcja);
  78. vect_alloc(vect_c, porcja);
  79. if (taskid == 0)
  80. {
  81. //wypelnienie macierzy A liczbami "losowymi"
  82. for (long i=0; i<rozmiar; ++i)
  83. for (long j=0; j<rozmiar; ++j)
  84. A[i][j] = (long)(sin(i) * i * j) % 10;
  85. //wypelnienie macierzy B liczbami "losowymi"
  86. for (long i=0; i<rozmiar; ++i)
  87. for (long j=0; j<rozmiar; ++j)
  88. B[i][j] = (long)(cos(j) *(i+j)) % 10;
  89. //dokonaj obracania macierzy
  90. for (long i=0; i<rozmiar; ++i)
  91. for (long j=0; j<rozmiar; ++j)
  92. B_rot[i*rozmiar+j] = B[j][i];
  93. }
  94. //wysyłanie macierzy A do wszystkich
  95. MPI::COMM_WORLD.Bcast(&A[0][0], rozmiar*rozmiar, MPI::LONG, 0);
  96. if (taskid == 0)
  97. {
  98. cout << endl << "WEKTOR DANYCH: " << endl;
  99. for (i=0; i<rozmiar*rozmiar; ++i)
  100. cout << B_rot[i] << " ";
  101. cout << endl;
  102. }
  103. MPI::COMM_WORLD.Barrier();
  104. //MPI::COMM_WORLD.Scatter(&B_rot[0], porcja, MPI::LONG, &vect[0], porcja, MPI::LONG, 0);
  105. // każdy proces ma policzyć łącznie "porcja" pól,
  106. // dlatego dostaje wektory kolumn, w których leżą porcje
  107. long pos, pocz, kon;
  108. for (i=0; i<ntasks; ++i)
  109. {
  110. porcja = (i == ntasks - 1) ? rozmiar*rozmiar%porcja : porcja;
  111. pos = i*porcja;
  112. pocz = pos - (pos%rozmiar);
  113. kon = pos+porcja - ((pos+porcja)%rozmiar) - 1;
  114. MPI::COMM_WORLD.Isend(&B_rot[pocz], kon-pocz, MPI::LONG, i, 0);
  115. }
  116. // w przypadku gdy iloraz wielkości macierzy i ilości programów daje resztę
  117. // wszystkie porcje zostają zwiększone, a ostatnia porcja w ostatnim programie
  118. // jest mniejsza - należy policzyć tą porcję zawczasu...
  119. /*
  120. tt.Begin();
  121. for (i=0; i<rozmiar; ++i)
  122. for (j=0; j<rozmiar; ++j)
  123. {
  124. C[i][j] = 0;
  125. for (long k=0; k<rozmiar; ++k)
  126. C[i][j] += A[i][k]*B[k][j];
  127. }
  128. long elapsed = tt.End();
  129. cout << "Time: " << elapsed << " ms" << endl;
  130. array_destroy(A);
  131. array_destroy(B);
  132. array_destroy(C);
  133. */
  134. /*
  135. cout << taskid << ": " ;
  136. for (i=0; i<porcja; ++i)
  137. cout << vect[i] << " ";
  138. cout << endl;
  139. */MPI::Finalize();
  140. exit(0);
  141. }