Untitled
unknown
plain_text
a year ago
5.4 kB
7
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