2012-12-13 164 views
0

我真的很喜歡MPI的東西。我只需要完成我的大學任務。有人能幫助我嗎?在矩陣MPI中查找最小值和最大值

任務是在N * M矩陣中查找最小值和最大值。進程計數必須等於N.我嘗試使用MPI_Reduce來查找最小值和最大值,但是我得到錯誤結果。這是我的代碼。

#include <mpi.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

const int n = 5; 
const int m = 4; 

void fill_matrix_randomly(int matrix[n][m], int max_value); 
void write_matrix(int matrix[n][m]); 
int find_max(int* vector, int vector_size); 
int find_min(int* vector, int vector_size); 
void write_vector(int* vector, int vector_size); 

int main(int argc, char* argv[]) 
{ 
    int my_rank = 0; 
    int comm_size = 0; 

    int a[n][m]; 
    int receive_buffer[m]; 
    int partial_max[m]; 
    int partial_min[m]; 

    MPI_Init(&argc, &argv); 

    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &comm_size); 

    if (comm_size != n) 
    { 
     printf("Please set process count = %d and run again.", n); 
     MPI_Finalize(); 
     return 0; 
    } 

    if (my_rank == 0) 
    { 
     fill_matrix_randomly(a, 10); 
     write_matrix(a);  
    } 
    /* MPI Scatter(address of send buffer, number of elements sent to each process, data type of send buffer, address of receive buffer, number of elements in receive buffer, data type of receive buffer, rank of sending process, communicators space) */ 
    MPI_Scatter(a, n, MPI_INT, receive_buffer, n, MPI_INT, 0, MPI_COMM_WORLD); 
    /* MPI_Reduce(address of send buffer, address of receive buffer, number of elements in send buffer, data type of elements in send buffer, reduce operation, rank of root process, communicators space) */ 
    MPI_Reduce(receive_buffer, partial_max, n, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); 
    MPI_Reduce(receive_buffer, partial_min, n, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); 
    if (my_rank == 0) 
    { 
     printf("Vector of partial max values.\n"); 
     write_vector(partial_max, n); 
     printf("Vector of partial min values.\n"); 
     write_vector(partial_min, n); 

     int max = find_max(partial_max, n); 
     int min = find_min(partial_min, n); 
     printf("Matrix boundaries = [%d..%d]\n", min, max); 
    } 
    MPI_Barrier(MPI_COMM_WORLD); 
    MPI_Finalize(); 

    return 0; 
} 

int find_max(int* vector, int vector_size) 
{ 
    int max = vector[0]; 
    int i = 0; 
    for (i = 0; i < vector_size; i++) 
    { 
     if (vector[i] > max) 
     { 
      max = vector[i]; 
     }  
    } 
    return max; 
} 

int find_min(int* vector, int vector_size) 
{ 
    int min = vector[0]; 
    int i = 0; 
    for (i = 0; i < vector_size; i++) 
    { 
     if (vector[i] < min) 
     { 
      min = vector[i]; 
     } 
    } 
    return min; 
} 

void fill_matrix_randomly(int matrix[n][m], int max_value) 
{ 
    int i = 0; 
    int j = 0; 
    srand(time(NULL)); 
    for (i = 0; i < n; i++) 
    { 
     for (j = 0; j < m; j++) 
     { 
      matrix[i][j] = rand() % max_value; 
     } 
    } 
} 

void write_matrix(int matrix[n][m]) 
{ 
    int i = 0; 
    int j = 0; 
    for (i = 0; i < n; i++) 
    { 
     for (j = 0; j < m; j++) 
     { 
      printf("%4d", matrix[i][j]);    
     } 
     printf("\n"); 
    } 
} 

void write_vector(int* vector, int vector_size) 
{ 
    int i = 0; 
    for (i = 0; i < vector_size; i++) 
    { 
     printf("vector[%d] = %d\n", i, vector[i]); 
    } 
} 

這裏是輸出。

$ mpiexec -n 5 ./main 
    8 1 3 9 
    1 0 3 1 
    4 9 5 5 
    1 7 4 9 
    8 5 7 4 
Vector of partial max values. 
vector[0] = 9 
vector[1] = 8 
vector[2] = 5 
vector[3] = 9 
vector[4] = 16 
Vector of partial min values. 
vector[0] = -1 
vector[1] = -1 
vector[2] = -1 
vector[3] = -1 
vector[4] = 1 
Matrix boundaries = [-1..16] 

我在哪裏錯了?我應該改變什麼?我花了整整一天的時間尋找解決方案。

回答

2

您的矩陣是nm列。當您將此矩陣分配到n進程時,每個進程必須處理m元素,但是在所有向量調用中使用的計數爲n。您應通過長度爲m的:

  • MPI_Scatter調用;
  • 均爲MPI_Reduce來電;
  • 均爲write_vector調用;
  • find_maxfind_min調用。

注意,您必須正確聲明receive_bufferpartial_maxpartial_minm元素。

+0

非常感謝!現在它工作正常。 –