Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.20 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<math.h>
  4. #include<time.h>
  5. #include<sys/time.h>
  6. #include <mpi.h>
  7.  
  8. #define in 60
  9. #define jn 60
  10. #define kn 60
  11. #define a 1
  12.  
  13. int I, J, K;
  14.  
  15. double Fresh(double, double, double);
  16. double Ro(double, double, double);
  17.  
  18. double *(F[2]), *(buffer[2]), hx, hy, hz, Fi, Fj, Fk, F1;
  19. double X = 2.0, Y = 2.0, Z = 2.0;
  20. double e = 0.00001;
  21. int L0 = 1, L1 = 0;
  22. int f, tmpF;
  23. int threadRank = 0, threadCount = 0;
  24. double owx, owy, owz;
  25.  
  26. int *perThreads, *offsets;
  27.  
  28. double c = 2 / owx + 2 / owy + 2 / owz + a;
  29. MPI_Request sendRequest[2] = {}, recRequest[2] = {};
  30.  
  31. /* Функция определения точного решения */
  32. double Fresh(double x, double y, double z) {
  33. double res;
  34. res = x + y + z;
  35. return res;
  36. }
  37.  
  38. /* Функция задания правой части уравнения */
  39. double Ro(double x, double y, double z) {
  40. double d;
  41. d = -a * (x + y + z);
  42. return d;
  43. }
  44.  
  45. void Inic(int *perThreads, int *offsets, int threadRank) {
  46. for (int i = 0, startLine = offsets[threadRank]; i <= perThreads[threadRank] - 1 ; i++, startLine++) {
  47. for (int j = 0; j <= jn; j++) {
  48. for (int k = 0; k <= kn; k++) {
  49. if ((startLine != 0) && (j != 0) && (k != 0) && (startLine != in) && (j != jn) && (k != kn)) {
  50. F[0][i*J*K + j*K + k] = 0;
  51. F[1][i*J*K + j*K + k] = 0;
  52. }
  53. else {
  54. F[0][i*J*K + j*K + k] = Fresh(startLine * hx, j * hy, k * hz);
  55. F[1][i*J*K + j*K + k] = Fresh(startLine * hx, j * hy, k * hz);
  56. }
  57. }
  58. }
  59. }
  60. }
  61.  
  62. }
  63.  
  64. void calcEdges() {
  65. for (int j = 1; j < jn; ++j) {
  66. for (int k = 1; k < kn; ++k) {
  67. if (threadRank != 0) {
  68. int i = 0;
  69. Fi = (F[L0][(i + 1)*J*K + j*K + k] + buffer[0][j*K + k]) / owx;
  70. Fj = (F[L0][i * J * K + (j + 1) * K + k] + F[L0][i * J * K + (j - 1) * K + k]) / owy;
  71. Fk = (F[L0][i * J * K + j * K + (k + 1)] + F[L0][i * J * K + j * K + (k - 1)]) / owz;
  72. F[L1][i*J*K + j*K + k] = (Fi + Fj + Fk - Ro((i + offsets[threadRank]) * hx, j * hy, k * hz)) / c;
  73. if (fabs(F[L1][i*J*K + j*K + k] - Fresh((i + offsets[threadRank]) * hx, j * hy, k * hz)) > e) {
  74. f = 0;
  75. }
  76. }
  77.  
  78. if (threadRank != threadCount - 1) {
  79. int i = perThreads[threadRank] - 1;
  80. Fi = (buffer[1][j*K + k] + F[L0][(i - 1)*J*K + j*K + k]) / owx;
  81. Fj = (F[L0][i * J * K + (j + 1) * K + k] + F[L0][i * J * K + (j - 1) * K + k]) / owy;
  82. Fk = (F[L0][i * J * K + j * K + (k + 1)] + F[L0][i * J * K + j * K + (k - 1)]) / owz;
  83. F[L1][i*J*K + j*K + k] = (Fi + Fj + Fk - Ro((i + offsets[threadRank]) * hx, j * hy, k * hz)) / c;
  84. if (fabs(F[L1][i*J*K + j*K + k] - Fresh((i + offsets[threadRank]) * hx, j * hy, k * hz)) > e) {
  85. f = 0;
  86. }
  87. }
  88. }
  89. }
  90. }
  91.  
  92. void sendData() {
  93. if (threadRank != 0) { //1
  94. MPI_Isend(&(F[L0][0]), K*J, MPI_DOUBLE, threadRank - 1, 0, MPI_COMM_WORLD, &sendRequest[0]); //низ
  95. MPI_Irecv(buffer[0], K*J, MPI_DOUBLE, threadRank - 1, 1, MPI_COMM_WORLD, &recRequest[1]);
  96. }
  97. if (threadRank != threadCount - 1) { //0
  98. MPI_Isend(&(F[L0][(perThreads[threadRank] - 1)*J*K]), K*J, MPI_DOUBLE, threadRank + 1, 1, MPI_COMM_WORLD, &s$
  99. MPI_Irecv(buffer[1], K*J, MPI_DOUBLE, threadRank + 1, 0, MPI_COMM_WORLD, &recRequest[0]);
  100. }
  101. }
  102.  
  103. void calcCenter() {
  104. for (int i = 1; i < perThreads[threadRank] - 1; ++i) {
  105. for (int j = 1; j < jn; ++j) {
  106. for (int k = 1; k < kn; ++k) {
  107. Fi = (F[L0][(i + 1)*J*K + j*K + k] + F[L0][(i - 1)*J*K + j*K + k]) / owx;
  108. Fj = (F[L0][i * J * K + (j + 1) * K + k] + F[L0][i * J * K + (j - 1) * K + k]) / owy;
  109. Fk = (F[L0][i * J * K + j * K + (k + 1)] + F[L0][i * J * K + j * K + (k - 1)]) / owz;
  110. F[L1][i*J*K + j*K + k] = (Fi + Fj + Fk - Ro((i + offsets[threadRank]) * hx, j * hy, k * hz)) / c;
  111. if (fabs(F[L1][i*J*K + j*K + k] - Fresh((i + offsets[threadRank]) * hx, j * hy, k * hz)) > e) {
  112. f = 0;
  113. }
  114. }
  115. }
  116. }
  117. }
  118.  
  119. void recData() {
  120. if (threadRank != 0) {
  121. MPI_Wait(&recRequest[1], MPI_STATUS_IGNORE);
  122. MPI_Wait(&sendRequest[0], MPI_STATUS_IGNORE);
  123. }
  124. if (threadRank != threadCount - 1) {
  125. MPI_Wait(&recRequest[0], MPI_STATUS_IGNORE);
  126. MPI_Wait(&sendRequest[1], MPI_STATUS_IGNORE);
  127. }
  128. }
  129.  
  130. void findMaxDiff() {
  131. double max = 0.0;
  132.  
  133. for (int i = 1; i < perThreads[threadRank] - 2; i++) {
  134. for (int j = 1; j < jn; j++) {
  135. for (int k = 1; k < kn; k++) {
  136. if ((F1 = fabs(F[L1][i*J*K + j*K + k] - Fresh((i + offsets[threadRank]) * hx, j * hy, k * hz))) > ma$
  137. max = F1;
  138. }
  139. }
  140. }
  141. }
  142.  
  143. double tmpMax = 0;
  144. MPI_Allreduce(&max, &tmpMax, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  145.  
  146. if (threadRank == 0) {
  147. max = tmpMax;
  148. printf("Max differ = %lf\n", max);
  149. }
  150. }
  151.  
  152. int main(int argc, char **argv) {
  153. MPI_Init(&argc, &argv);
  154.  
  155. MPI_Comm_size(MPI_COMM_WORLD, &threadCount);
  156. MPI_Comm_rank(MPI_COMM_WORLD, &threadRank);
  157.  
  158. if (threadRank == 0) {
  159. printf("Thread count: %d\n", threadCount);
  160. }
  161.  
  162. perThreads = new int[threadCount]();
  163. offsets = new int[threadCount]();
  164.  
  165. for (int i = 0, height = kn + 1, tmp = threadCount - (height % threadCount), currentLine = 0; i < threadCount; +$
  166. offsets[i] = currentLine;
  167. perThreads[i] = i < tmp ? (height / threadCount) : (height / threadCount + 1);
  168. currentLine += perThreads[i];
  169. }
  170.  
  171. I = perThreads[threadRank];
  172. J = (jn + 1);
  173. K = (kn + 1);
  174.  
  175. F[0] = new double[I * J * K]();
  176. F[1] = new double[I * J * K]();
  177.  
  178. buffer[0] = new double[K*J]();
  179. buffer[1] = new double[K*J]();
  180.  
  181. /* Размеры шагов */
  182. hx = X / in;
  183. hy = Y / jn;
  184. hz = Z / kn;
  185.  
  186. owx = pow(hx, 2);
  187. owy = pow(hy, 2);
  188. owz = pow(hz, 2);
  189. c = 2 / owx + 2 / owy + 2 / owz + a;
  190.  
  191. Inic(perThreads, offsets, threadRank);
  192.  
  193. double start = MPI_Wtime();
  194.  
  195. do {
  196. f = 1;
  197. L0 = 1 - L0;
  198. L1 = 1 - L1;
  199.  
  200. //обмениваемся краями
  201. sendData();
  202.  
  203. //считаем середину
  204. calcCenter();
  205.  
  206.  
  207. //Ждем получения всех данных
  208. recData();
  209.  
  210. //считаем края
  211. calcEdges();
  212.  
  213. MPI_Allreduce(&f, &tmpF, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
  214. f = tmpF;
  215. }
  216. while (f == 0);
  217.  
  218. double finish = MPI_Wtime();
  219.  
  220. if (threadRank == 0) {
  221. printf("Time: %lf\n", finish - start);
  222. }
  223.  
  224. findMaxDiff();
  225.  
  226. delete[] buffer[0];
  227. delete[] buffer[1];
  228. delete[] F[0];
  229. delete[] F[1];
  230. delete[] offsets;
  231. delete[] perThreads;
  232.  
  233. MPI_Finalize();
  234. return 0;
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement