Untitled
unknown
c_cpp
2 years ago
5.5 kB
9
Indexable
התרגיל :
נתונים המערכים 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]);
}
}Editor is loading...
Leave a Comment