Untitled
unknown
c_cpp
7 months ago
5.5 kB
1
Indexable
Never
התרגיל : נתונים המערכים D ,C ,B ,A הידועים לתהליכים 3P 2,P 1,P 0,P בהתאמה. המערכים בגודל N כל אחד ומכילים מספרים שלמים. מטרת התוכנית היא להדפיס את כל האיברים של מערך A ושל מערך B שעבורם מתקיימים התנאים: f(A[i]) > C[i] f(B[i]) < D[i] הדרישות: • יש לכתוב תכנית מקבילית יעילה המשתמשת ב- MPI וב- OpenMP . • ברשותכם שני מחשבים עם ארבע ליבות כל אחד. • כל ההדפס ות יבוצעו על תהליך עם ראנק (rank (.0 • יש להשתמש בפונקציות Gather_MPI ו-Scatter_MPI בכל מקום מתאים. • אפשר להניח שהמספר N מתחלק ב.8- • הפונקציה f מקבלת פרמטר מסוג int ומחזירה מספר double. הפונקציה נחשבת כמאוד כבדה, אין צורך ליישם אותה. • אין צורך לאתחל את המערכים D ,C ,B ,A. אני עשיתי פתרון ל2 מחשבים ו4 ליבות כל אחד. ובלי הפונקציות שביקשו.. פתרון שלי : #include <mpi.h> #include <stdio.h> #include <omp.h> #include <math.h> #include <stdlib.h> void print_elements(int *A, int *B, int *result_A, int *result_B, int N) { for (inti = 0; i < N; i++) { if (result_A[i]) printf("%d ", A[i]); if (result_B[i]) printf("%d ", B[i]); } } double f(int x) { double res = 0.0; for (int i = 0; i < 10; i++) { res += sin(x * i) * cos(x * i) / (i + 1); } return res; } int readA(**A); int readB(**B); int readC(**C); int readD(**D); int main(int argc, char **argv) { int rank, size, N; int *A, *B, *C, *D, *result_A, *result_B; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { N = readA(&A); // assume he reads the array and return the size ! readC(&C); // assume he reads the array and return the size ! } if (rank == 1) { N = readB(&B);// assume he reads the array and return the size ! readD(&D);// assume he reads the array and return the size ! } if (rank == 0) { result_A = calloc(N, sizeof(int)); //rank 0 will calc by him self result_B = malloc(N * sizeof(int));//will be filled from rank 1 // Compute result_A #pragma omp parallel for num_threads(4) for (int i = 0; i < N; i++) { if (f(A[i]) > C[i]) result_A[i] = 1; } MPI_Recv(result_B, N, MPI_INT, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); print_elements(rank, A, B, result_A, result_B, N); } else { result_B = calloc(N, sizeof(int); // Compute result_B #pragma omp parallel for num_threads(4) for (int i = 0; i < N; i++) { if (f(B[i]) < D[i]) result_B[i] = 1; } MPI_Send(result_B, N, MPI_INT, 0, 0, MPI_COMM_WORLD); } MPI_Finalize(); return 0; } // פתרון שלהם int rank, size, i, j, nproc; int data[2]; int A[N], B[N], C[N], D[N]; int part = N/4; // מחלקים לכל אחד רבע מערך לחישוב int a[N/4], b[N/4], c[N/4], d[N/4], result_a[N/4], result_b[N/4]; int count, count_a, count_b; MPI_Status status; int *arr; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nproc); int numOfElements; if (rank == 0) { numOfElements = N; for (i = 0; i < N; i++) A[i] = i; B[i] = i; C[i] = i; D[i] = i; } // מפזרים לכל תהליך מתוך ה4 רבע מכל מערך שעליו הוא יעבוד MPI_Scatter(A, PART, MPI_INT, a, PART, MPI_INT, 0, MPI_COMM_WORLD); MPI_Scatter(B, PART, MPI_INT, b, PART, MPI_INT, 1, MPI_COMM_WORLD); MPI_Scatter(C, PART, MPI_INT, c, PART, MPI_INT, 2, MPI_COMM_WORLD); MPI_Scatter(D, PART, MPI_INT, d, PART, MPI_INT, 3, MPI_COMM_WORLD); count_a = 0; count_b = 0; // אינדקסים לשליטה על הקמת המערך החדש עם הערכים שצריך להדפיס #pragma omp parallel for for (i = 0; i < PART; i++) { if (f(a[i]) > c[i]) result_a[count_a++] = a[i]; if (f(b[i]) < d[i]) result_b[count_b++] = b[i]; } if (rank != 0) { // נעביר את המידע שצברנו וכאן זה מחזיר באמצעות דאבל סוג של קאסטינג MPI_Send(result_a, count_a, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); MPI_Send(result_b, count_b, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); printf("rank = %d\n", rank); } else {//rank 0 יעשה את זה for (i = 1; i < nproc; i++) { // דורסים מערך קיים כדי לנצל שהוא קיים וניקח ממנו רק את החלקים שנרצה להדפסה בעזרת ה גט קאונט הזה. MPI_Recv(A, PART, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_DOUBLE, &count); printf("A\n"); for (j = 0; j < count; j++) printf("%e\n", A[j]); } for (i = 1; i < nproc; i++) { MPI_Recv(B, PART, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_DOUBLE, &count); printf("B\n"); for (j = 0; j < count; j++) printf("%e\n", B[j]); } }
Leave a Comment