2012-12-13 11 views
25

Cho đến nay, ứng dụng của tôi đang đọc trong một tệp txt với một danh sách các số nguyên. Các số nguyên này cần phải được lưu trữ trong một mảng bằng quy trình tổng thể, tức là bộ vi xử lý có thứ hạng 0. Điều này hoạt động tốt.MPI_Scatter và MPI_Gather được sử dụng như thế nào từ C?

Bây giờ, khi tôi chạy chương trình, tôi có một câu lệnh if kiểm tra xem đó là quy trình chính và nếu có, tôi đang thực hiện lệnh MPI_Scatter.

Từ những gì tôi hiểu điều này sẽ chia nhỏ mảng bằng các số và chuyển nó sang các quy trình phụ, tức là tất cả có xếp hạng> 0. Tuy nhiên, tôi không chắc chắn cách xử lý MPI_Scatter. Làm thế nào để quá trình nô lệ "đăng ký" để có được mảng phụ? Làm thế nào tôi có thể nói cho các quy trình không chính để làm điều gì đó với mảng phụ?

Có thể ai đó vui lòng cung cấp một ví dụ đơn giản để chỉ cho tôi cách thức quy trình tổng thể gửi các phần tử từ mảng và sau đó có nô lệ thêm tổng và trả lại giá trị này cho tổng thể và in ra?

Mã của tôi cho đến nay:

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

//A pointer to the file to read in. 
FILE *fr; 

int main(int argc, char *argv[]) { 

int rank,size,n,number_read; 
char line[80]; 
int numbers[30]; 
int buffer[30]; 

MPI_Init(&argc, &argv); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 

fr = fopen ("int_data.txt","rt"); //We open the file to be read. 

if(rank ==0){ 
printf("my rank = %d\n",rank); 

//Reads in the flat file of integers and stores it in the array 'numbers' of type int. 
n=0; 
while(fgets(line,80,fr) != NULL) { 
    sscanf(line, "%d", &number_read); 
    numbers[n] = number_read; 
    printf("I am processor no. %d --> At element %d we have number: %d\n",rank,n,numbers[n]); 
    n++; 
} 

fclose(fr); 

MPI_Scatter(&numbers,2,MPI_INT,&buffer,2,MPI_INT,rank,MPI_COMM_WORLD); 

} 
else { 
MPI_Gather (&buffer, 2, MPI_INT, &numbers, 2, MPI_INT, 0, MPI_COMM_WORLD); 
printf("%d",buffer[0]); 
} 
MPI_Finalize(); 
return 0; 
} 

Trả lời

56

Đây là một hiểu lầm phổ biến về cách thức hoạt động làm việc trong Bộ KH & ĐT với những người mới đến nó; đặc biệt là với các hoạt động tập thể, nơi mọi người cố gắng bắt đầu sử dụng chương trình phát sóng (MPI_Bcast) chỉ từ thứ hạng 0, mong đợi cuộc gọi bằng cách nào đó "đẩy" dữ liệu đến các bộ xử lý khác. Nhưng đó không thực sự là cách thức hoạt động của MPI; hầu hết giao tiếp MPI yêu cầu cả người gửi và người nhận thực hiện cuộc gọi MPI.

Cụ thể, MPI_Scatter()MPI_Gather() (và MPI_Bcast và nhiều người khác) là tập thể hoạt động; họ phải được gọi bằng tất cả của các tác vụ trong bộ giao tiếp. Tất cả các bộ vi xử lý trong giao tiếp thực hiện cùng một cuộc gọi và thao tác được thực hiện. (Đó là lý do tại sao phân tán và thu thập cả hai yêu cầu như là một trong các tham số "gốc" quá trình, nơi mà tất cả các dữ liệu đi vào/đến từ). Bằng cách làm theo cách này, việc thực hiện Bộ KH & ĐT có rất nhiều phạm vi để tối ưu hóa các mẫu giao tiếp.

Vì vậy, đây là một ví dụ đơn giản (Cập nhật bao gồm thu thập):

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

int main(int argc, char **argv) { 
    int size, rank; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    int *globaldata=NULL; 
    int localdata; 

    if (rank == 0) { 
     globaldata = malloc(size * sizeof(int)); 
     for (int i=0; i<size; i++) 
      globaldata[i] = 2*i+1; 

     printf("Processor %d has data: ", rank); 
     for (int i=0; i<size; i++) 
      printf("%d ", globaldata[i]); 
     printf("\n"); 
    } 

    MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD); 

    printf("Processor %d has data %d\n", rank, localdata); 
    localdata *= 2; 
    printf("Processor %d doubling the data, now has %d\n", rank, localdata); 

    MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD); 

    if (rank == 0) { 
     printf("Processor %d has data: ", rank); 
     for (int i=0; i<size; i++) 
      printf("%d ", globaldata[i]); 
     printf("\n"); 
    } 

    if (rank == 0) 
     free(globaldata); 

    MPI_Finalize(); 
    return 0; 
} 

Chạy nó mang lại:

gpc-f103n084-$ mpicc -o scatter-gather scatter-gather.c -std=c99 
gpc-f103n084-$ mpirun -np 4 ./scatter-gather 
Processor 0 has data: 1 3 5 7 
Processor 0 has data 1 
Processor 0 doubling the data, now has 2 
Processor 3 has data 7 
Processor 3 doubling the data, now has 14 
Processor 2 has data 5 
Processor 2 doubling the data, now has 10 
Processor 1 has data 3 
Processor 1 doubling the data, now has 6 
Processor 0 has data: 2 6 10 14 
+2

Thật là một câu trả lời tuyệt vời. Làm cho nó rất thẳng về phía trước và tôi thấy nó hoạt động như thế nào bây giờ. Tôi đã phạm sai lầm khi không nghĩ về nó như là các hoạt động tập thể. Cảm ơn rất nhiều! – DSF

+2

Thật tuyệt vời! Bạn đã cứu ngày của tôi, Chúc mừng. Cảm ơn bạn – irobo

+0

Hữu ích hơn hầu hết các phần giới thiệu MPI – WakaChewbacca