Untitled
unknown
plain_text
2 years ago
5.4 kB
16
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
typedef int (*LocalMaxFunction)(int array[], unsigned int start, const unsigned int end, int *local_max);
int Parallel_Local_Max(int array[], unsigned int start, const unsigned int end, int *local_max);
int StrictlyDiagonallyDominantParallel(int array[], unsigned int start, const unsigned int end, LocalMaxFunction local_max, int *k, int rank, int size);
void CreateMatrixBParallel(int *A, int *B, int m, int *min_element, int *min_element_i, int *min_element_j, int rank, int size);
void Display_B_Array(int *b, const unsigned int end);
void Display_B_Array(int *b, const unsigned int end) {
for (unsigned int i = 0; i < end; i++) {
for (unsigned int j = 0; j < end; j++) {
printf("%d ", *(b + i * end + j));
}
printf("\n");
}
}
int Parallel_Local_Max(int array[], unsigned int start, const unsigned int end, int *local_max) {
*local_max = abs(*(array+start)); // Initialize local_max with the absolute value of the first element
for (unsigned int i = start + 1; i < end; i++) {
if (abs(*(array+i*end+i)) > *local_max) {
*local_max = abs(*(array+i*end+i));
}
}
return *local_max;
}
int StrictlyDiagonallyDominantParallel(int array[], unsigned int start, const unsigned int end, LocalMaxFunction local_max, int *k, int rank, int size) {
int StrictlyDiagonallyDominant = 1;
int local_max_absolute_value = local_max(array, start, end, k);
for (unsigned int i = start; i < end; i++) {
int diagonalValue = abs(*(array+i*end+i));
int offDiagonalSum = 0;
for (int j = 0; j < end; j++) {
if (j != i) {
offDiagonalSum += abs(*(array+i*end+j));
}
}
if (diagonalValue <= offDiagonalSum) {
StrictlyDiagonallyDominant = 0;
break;
}
}
MPI_Allreduce(&local_max_absolute_value, k, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
MPI_Bcast(&StrictlyDiagonallyDominant, 1, MPI_INT, 0, MPI_COMM_WORLD);
return StrictlyDiagonallyDominant;
}
void CreateMatrixBParallel(int *A, int *B, int m, int *min_element, int *min_element_i, int *min_element_j, int rank, int size) {
*min_element = m;
*min_element_i = 0;
*min_element_j = 0;
int elements_per_process = m * m / size;
int start_index = rank * elements_per_process;
int end_index = (rank + 1) * elements_per_process;
for (int index = start_index; index < end_index; index++) {
int i = index / m;
int j = index % m;
if (i != j) {
*(B+index) = m - abs(A[i * m + j]); *(A+i*m+j)
// Update min_element information
if (*(B+index) < *min_element) {
*min_element = *(B+index);
*min_element_i = i;
*min_element_j = j;
}
} else {
*(B+index) = m;
}
}
}
int main(int argc, char *argv[]) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int *A = NULL;
int *B = NULL;
int N;
if (rank == 0) {
printf("Enter the size of the matrix (N): ");
scanf("%d", &N);
while (N % size != 0) {
printf("Enter a size that is an integer multiple of the number of processes!\n");
scanf("%d", &N);
}
}
// Broadcast N to all processors
MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
A = (int *)malloc(N * N * sizeof(int));
B = (int *)malloc(N * N * sizeof(int));
int maxAbsoluteValue = 0;
// Processor 0 reads the matrix
if (rank == 0) {
printf("Enter the elements of the matrix A(%dx%d):\n", N, N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
scanf("%d", &*(A+i*N+j));
}
}
}
// Broadcast matrix A to all processors
MPI_Bcast(A, N * N, MPI_INT, 0, MPI_COMM_WORLD);
int rows_per_process = N / size;
int start_row = 0;
int end_row = N;
int local_max = 0;
int isStrictlyDiagonallyDominant = StrictlyDiagonallyDominantParallel(A, start_row, end_row, Parallel_Local_Max, &local_max, rank, size);
MPI_Barrier(MPI_COMM_WORLD);
// Parallel computation for matrix B
int min_element, min_element_i, min_element_j;
CreateMatrixBParallel(A, B, N, &min_element, &min_element_i, &min_element_j, rank, size);
// Use MPI_Reduce to find the global minimum and its position
int global_min_element, global_min_element_i, global_min_element_j;
MPI_Reduce(&min_element, &global_min_element, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
MPI_Reduce(&min_element_i, &global_min_element_i, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
MPI_Reduce(&min_element_j, &global_min_element_j, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0) {
if (isStrictlyDiagonallyDominant == 1) {
printf("The matrix A is strictly diagonally dominant: yes\n");
printf("Maximum absolute value on the diagonal: %d\n", local_max);
printf("Matrix B:\n");
Display_B_Array(B, N);
} else {
printf("The matrix A is not strictly diagonally dominant: no\n");
}
}
free(A);
free(B);
MPI_Finalize();
return 0;
}
Editor is loading...
Leave a Comment