2012-12-13 42 views
25

अभी तक, मेरा आवेदन पूर्णांक की सूची के साथ एक txt फ़ाइल में पढ़ रहा है। इन पूर्णांकों को मास्टर प्रोसेस i.e. प्रोसेसर द्वारा रैंक 0 के साथ सरणी में संग्रहीत करने की आवश्यकता है। यह ठीक काम कर रहा है।MPI_Scatter और MPI_Gather सी से कैसे उपयोग किए जाते हैं?

अब, जब मैं प्रोग्राम चलाता हूं तो मेरे पास एक कथन कथन है कि यह मास्टर प्रक्रिया है और यदि यह है, तो मैं MPI_Scatter कमांड निष्पादित कर रहा हूं।

जो मैं समझता हूं उससे सरणी को संख्याओं के साथ विभाजित कर देगा और इसे गुलाम प्रक्रियाओं में भेज दिया जाएगा यानी सभी रैंक> 0 के साथ। हालांकि, मुझे यकीन नहीं है कि MPI_Scatter को कैसे संभालें। उप-सरणी प्राप्त करने के लिए दास "सब्सक्राइब" प्रक्रिया कैसे करता है? उप-सरणी के साथ कुछ करने के लिए मैं गैर-मास्टर प्रक्रियाओं को कैसे बता सकता हूं?

क्या कोई मुझे यह दिखाने के लिए एक सरल उदाहरण प्रदान कर सकता है कि मास्टर प्रक्रिया सरणी से तत्व कैसे भेजती है और उसके बाद दास राशि जोड़ते हैं और इसे मास्टर को वापस कर देते हैं, जो सभी रकम को एक साथ जोड़ता है और इसे प्रिंट करता है?

मेरे कोड अब तक:

#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; 
} 

उत्तर

56

इस तरह के आपरेशनों यह करने के लिए नए लोगों के साथ एमपीआई में काम का एक आम गलतफहमी है, विशेष रूप से सामूहिक परिचालनों के साथ, जहां लोग रैंक 0 से प्रसारण (MPI_Bcast) का उपयोग शुरू करने का प्रयास करते हैं, कॉल को अन्य प्रोसेसर को डेटा को "धक्का" देने की अपेक्षा करते हैं। लेकिन वास्तव में यह नहीं है कि MPI दिनचर्या कैसे काम करती है; अधिकांश एमपीआई संचार में प्रेषक और रिसीवर दोनों को एमपीआई कॉल करने की आवश्यकता होती है।

विशेष रूप से, MPI_Scatter() और MPI_Gather() (और MPI_Bcast, और कई अन्य) सामूहिक संचालन कर रहे हैं; उन्हें संचारक में कार्यों के सभी द्वारा बुलाया जाना है। संचारक के सभी प्रोसेसर एक ही कॉल करते हैं, और ऑपरेशन किया जाता है। (यही कारण है कि स्कैटर और इकट्ठा दोनों को "रूट" प्रक्रिया के पैरामीटर में से एक के रूप में आवश्यक है, जहां सभी डेटा/से आता है)। इस तरह से, एमपीआई कार्यान्वयन में संचार पैटर्न को अनुकूलित करने के लिए बहुत अधिक गुंजाइश है।

#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; 
} 

चल रहा है यह देता है::

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

क्या एक उत्कृष्ट जवाब

तो यहाँ एक सरल उदाहरण (अपडेट किया गया इकट्ठा शामिल करने के लिए) है। इसे बहुत सीधे आगे बढ़ाया और मैं देखता हूं कि यह अब कैसे काम करता है। मैंने सामूहिक परिचालन के रूप में इसके बारे में सोचने की गलती की। बहुत बहुत धन्यवाद! – DSF

+2

वाह! आपने मेरा दिन बचाया, चीयर्स। धन्यवाद – irobo

+0

अधिकतर एमपीआई इंट्रोस से अधिक उपयोगी – WakaChewbacca