Untitled

mail@pastecode.io avatar
unknown
plain_text
2 months ago
5.4 kB
3
Indexable
Never
#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;
}
Leave a Comment