2016-10-10 14 views
9

यह प्रोग्राम सी लग्रेंज और एमपीआई का उपयोग करके लिखा गया है। मैं एमपीआई के लिए नया हूं और प्रक्रियाओं समेत कुछ गणना करने के लिए सभी प्रोसेसर का उपयोग करना चाहता हूं। इस अवधारणा को जानने के लिए, मैंने निम्नलिखित सरल कार्यक्रम लिखा है। लेकिन इस कार्यक्रम प्रक्रिया 0 से इनपुट प्राप्त करने के बाद निचले भाग में लटकी हुई है और परिणाम प्रक्रिया 0.सभी प्रोसेसर का उपयोग करके एमपीआई में कैसे भेजें/प्राप्त करें

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

int main(int argc, char** argv) {  
    MPI_Init(&argc, &argv); 
    int world_rank; 
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
    int world_size; 
    MPI_Comm_size(MPI_COMM_WORLD, &world_size); 

    int number; 
    int result; 
    if (world_rank == 0) 
    { 
     number = -2; 
     int i; 
     for(i = 0; i < 4; i++) 
     { 
      MPI_Send(&number, 1, MPI_INT, i, 0, MPI_COMM_WORLD); 
     } 
     for(i = 0; i < 4; i++) 
     {   /*Error: can't get result send by other processos bellow*/ 
      MPI_Recv(&number, 1, MPI_INT, i, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 
      printf("Process 0 received number %d from i:%d\n", number, i); 
     } 
    } 
    /*I want to do this without using an else statement here, so that I can use process 0 to do some calculations as well*/ 

    MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 
    printf("*Process %d received number %d from process 0\n",world_rank, number); 
    result = world_rank + 1; 
    MPI_Send(&result, 1, MPI_INT, 0, 99, MPI_COMM_WORLD); /* problem happens here when trying to send result back to process 0*/ 

    MPI_Finalize(); 
} 

runing और हो रही परिणामों में वापस नहीं भेजेंगे:

:$ mpicc test.c -o test 
:$ mpirun -np 4 test 

*Process 1 received number -2 from process 0 
*Process 2 received number -2 from process 0 
*Process 3 received number -2 from process 0 
/* hangs here and will not continue */ 

आप कर सकते हैं, तो , कृपया मुझे उदाहरण के साथ दिखाएं या उपरोक्त कोड को संपादित करें यदि संभव हो।

उत्तर

1

मुझे वास्तव में काम नहीं करता है कि वर्किंग डोमेन के आस-पास 2 if कथन का उपयोग करने में क्या गलत होगा। लेकिन वैसे भी, यहां एक उदाहरण दिया जा सकता है कि क्या किया जा सकता है।

मैंने सामूहिक संचार का उपयोग करने के लिए आपके कोड को संशोधित किया क्योंकि वे आपके द्वारा उपयोग/प्राप्त करने की श्रृंखला की तुलना में अधिक समझ में आते हैं। चूंकि शुरुआती संचार एक समान मूल्य के साथ हैं, इसलिए मैं MPI_Bcast() का उपयोग करता हूं जो एक ही कॉल में समान होता है।
इसके विपरीत, चूंकि परिणाम मान अलग-अलग हैं, MPI_Gather() पर कॉल पूरी तरह उपयुक्त है।
मैं अपने परिणामों को वापस भेजने से पहले प्रक्रियाओं को थोड़ी देर के लिए काम कर रहा हूं, यह अनुकरण करने के लिए sleep() पर एक कॉल भी पेश करता हूं।

कोड अब इस तरह दिखता है:

$ mpicc -std=c99 simple_mpi.c -o simple_mpi 

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

#include <mpi.h> 
#include <stdlib.h> // for malloc and free 
#include <stdio.h> // for printf 
#include <unistd.h> // for sleep 

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

    MPI_Init(&argc, &argv); 
    int world_rank; 
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
    int world_size; 
    MPI_Comm_size(MPI_COMM_WORLD, &world_size); 

    // sending the same number to all processes via broadcast from process 0 
    int number = world_rank == 0 ? -2 : 0; 
    MPI_Bcast(&number, 1, MPI_INT, 0, MPI_COMM_WORLD); 
    printf("Process %d received %d from process 0\n", world_rank, number); 

    // Do something usefull here 
    sleep(1); 
    int my_result = world_rank + 1; 

    // Now collecting individual results on process 0 
    int *results = world_rank == 0 ? malloc(world_size * sizeof(int)) : NULL; 
    MPI_Gather(&my_result, 1, MPI_INT, results, 1, MPI_INT, 0, MPI_COMM_WORLD); 

    // Process 0 prints what it collected 
    if (world_rank == 0) { 
     for (int i = 0; i < world_size; i++) { 
      printf("Process 0 received result %d from process %d\n", results[i], i); 
     } 
     free(results); 
    } 

    MPI_Finalize(); 

    return 0; 
} 

यह संकलन के रूप में इस के बाद

$ mpiexec -n 4 ./simple_mpi 
Process 0 received -2 from process 0 
Process 1 received -2 from process 0 
Process 3 received -2 from process 0 
Process 2 received -2 from process 0 
Process 0 received result 1 from process 0 
Process 0 received result 2 from process 1 
Process 0 received result 3 from process 2 
Process 0 received result 4 from process 3 
1

वास्तव में, प्रक्रियाओं 1-3 वास्तव में परिणाम प्रोसेसर 0 पर वापस भेज रहे हैं। हालांकि, प्रोसेसर 0 इस लूप के पहले पुनरावृत्ति में फंस गया है:

for(i=0; i<4; i++) 
{  
    MPI_Recv(&number, 1, MPI_INT, i, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 
    printf("Process 0 received number %d from i:%d\n", number, i); 
} 

पहले MPI_Recv कॉल में, प्रोसेसर 0 टैग 99 के साथ ही एक संदेश प्राप्त करने के लिए इंतजार कर रहे अवरुद्ध कर देगा संदेश 0 अभी तक नहीं भेजा था कि।

आम तौर पर, प्रोसेसर के लिए संदेशों को भेजने/प्राप्त करने के लिए यह एक बुरा विचार है, खासकर ब्लॉकिंग कॉल का उपयोग करना। 0 में पहले से ही स्मृति में मूल्य है। इसे खुद को भेजने की आवश्यकता नहीं है।

Process 1 received number -2 from process 0 
Process 2 received number -2 from process 0 
Process 3 received number -2 from process 0 
Process 0 received number 2 from i:1 
Process 0 received number 3 from i:2 
Process 0 received number 4 from i:3 
Process 0 received number -2 from process 0 

ध्यान दें कि के रूप में गाइल्स ने उल्लेख किया MPI_Bcast और MPI_Gather का उपयोग कर एक है:

हालांकि, एक वैकल्पिक हल अब कोड चलाने से आपको दे देंगे से i=1

for(i=1; i<4; i++) 
{   
    MPI_Recv(&number, 1, MPI_INT, i, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 
    printf("Process 0 received number %d from i:%d\n", number, i); 
} 

पाश प्राप्त शुरू करने के लिए है डेटा वितरण/संग्रह के लिए अधिक कुशल और मानक तरीका।

संबंधित मुद्दे