2012-05-18 10 views
6

एक प्रतीत होता है मूर्ख सवाल है, लेकिन मुझे एक निश्चित उत्तर एक या दूसरे तरीके से नहीं मिल रहा है।क्या मुझे एमपीआई :: Isend के लिए एक संबंधित एमपीआई :: Irecv होना चाहिए?

मूल प्रश्न क्या मुझे एक एमपीआई :: Isend के लिए संबंधित एमपीआई :: Irecv होना चाहिए?

यही है, भले ही संदेश भेजने, गैर अवरुद्ध है जब तक मैं इंतजार भेजने बफ़र्स पुन: उपयोग से पहले पूरा करने के लिए भेजता है, मैं गैर अवरुद्ध का उपयोग करने के & इंतजार प्राप्त भेजा बफ़र्स प्राप्त करने के लिए की जरूरत है?

मेरा मुद्दा यह है कि, मैं संदेश भेज रहा हूं, जबकि गैर-अवरोधन "अन्य सामान" करने के लिए भेजता है लेकिन रिसीवर प्रक्रिया तुरंत बफर का उपयोग करेगी, इसलिए मैं उन्हें बफर को वास्तव में प्राप्त होने तक अवरुद्ध करना चाहता हूं।

ऐसा लगता है कि मुझे MPI :: Recv के साथ संदेश प्राप्त करने में सक्षम होना चाहिए, भले ही उन्हें MPI :: Isend के साथ भेजा गया हो लेकिन मुझे आश्चर्य है कि मुझे कुछ याद आ रहा है?

सरल छद्म एक छोटा सा कोड

if(rank == 0){ 
    int r; 
    for (int i = 0; i < n; i++){ 

    // DO SOME STUFF HERE... 

    request.Wait(status); 
    request2.Wait(status); 
    request3.Wait(status); 

    r = i; 
    memcpy(key, fromKey(i), ...); 
    memcpy(trace, fromTrace(i), ...); 

    request = MPI::COMM_WORLD.Isend(&r, 1, MPI::INT, node, tag); 
    request2 = MPI::COMM_WORLD.Isend(key, 10, MPI::INT, node, tag); 
    request3 = MPI::COMM_WORLD.Isend(trace, nBytesTotal, MPI::BYTE, node, tag); 

    // DO SOME MORE STUFF HERE. 

    } 
    r = -1; 
    request = MPI::COMM_WORLD.Isend(&r, 1, MPI::INT, node, tag); 

    // Carry on ... 

    } else { 

    int r = -1; 
    MPI::COMM_WORLD.Recv(&r, 1, MPI::INT, 0, tag, status); 
    while(r >= 0){ 

    MPI::COMM_WORLD.Recv(&key, 10, MPI::INT, 0, tag, status); 
    memcpy(saveKey, key, ...); 

    MPI::COMM_WORLD.Recv(&trace, nBytesTotal, MPI::BYTE, 0, tag, status); 
    memcpy(saveTrace, trace, ...); 

    MPI::COMM_WORLD.Recv(&r, 1, MPI::INT, 0, tag, status); 
    } 
+0

यहां का जवाब आपको रूचि दे सकता है: http://stackoverflow.com/questions/9408704/mpi-send-and-receive-questions –

उत्तर

15

नहीं, आप संचार के दोनों सिरों पर अवरुद्ध और गैर-अवरुद्ध एमपीआई संचालन को स्वतंत्र रूप से मिश्रण कर सकते हैं। अवरोध तब से संबंधित होता है जब एमपीआई कॉल आपके कोड पर नियंत्रण लौटाता है, न कि प्रेषित होने वाले संदेश की सामग्री के लिए।

प्रत्येक एमपीआई संदेश में स्वयं के साथ एक "लिफाफा" होता है, जिसमें इसका स्रोत, गंतव्य, टैग और संचारक होता है। सफलतापूर्वक एक संदेश प्राप्त करने के लिए आपके प्राप्त ऑपरेशन को केवल अपने लिफाफा से मेल खाना चाहिए। लिफ़ाफ़ा किसी भी तरह से निर्दिष्ट नहीं करता है कि संदेश को वास्तव में कैसे भेजा गया था - क्या यह अवरोधन के माध्यम से था, यह एक गैर-अवरुद्ध ऑपरेशन के माध्यम से था, क्या यह एक तुल्यकालिक प्रेषण (MPI_Ssend) या एक buffered एक (MPI_Bsend) था। एकमात्र अपवाद तथाकथित "तैयार मोड" भेजता है जिसे MPI_Rsend() या MPI_Irsend() के साथ शुरू किया गया है, जिसके लिए मिलान प्राप्त करने वाला ऑपरेशन पहले ही पोस्ट कर दिया गया है या संदेश वितरित नहीं किया जाएगा।

यही कारण है कि "मिलान प्राप्त ऑपरेशन" शब्द का उपयोग एमपीआई मानक में किया जाता है और कुछ "संबंधित प्राप्त कार्य" जैसा नहीं होता है।

+0

तो जवाब है "नहीं, आपको एमपीआई :: आइसेंड के लिए संबंधित एमपीआई :: Irecv रखने की आवश्यकता नहीं है"। यही तो मैने सोचा। अगर यह अन्यथा था, तो मुझे आश्चर्य होगा। विवरण के लिए धन्यवाद। – user1074069

+0

मेरे बिंदु को और अधिक स्पष्ट बनाने के लिए संपादित :) –

0

हाँ, यह ठीक है। कोई आवश्यकता नहीं है कि भेजें/recv "प्रकार" (या जो भी आप उन्हें कॉल करना चाहते हैं) मैच।

+0

यही मैंने सोचा था। अगर यह अन्यथा था, तो मुझे आश्चर्य होगा। मुझे लगता है कि मैं वास्तव में चिंतित था कि किसी भी कार्यान्वयन में उस मामले में कुछ अजीब बात हो रही है। – user1074069

0

इससे कोई फर्क नहीं पड़ता कि आप किस संदेश/आरईवी का उपयोग करते हैं; लेकिन कार्यान्वयन महत्वपूर्ण है। आपको अपने कोड में अवरुद्ध बिंदुओं से अवगत होना चाहिए। उदाहरण के संचार आप ध्यान होना चाहिए अवरुद्ध का उपयोग कर में लिए के बारे में भेजने के लिए और इस कोड को

if(rank==0) 
{ 
MPI_Send(x to process 1) 
MPI_Recv(y from process 1) 
} 
if(rank==1) 
{ 
MPI_Send(y to process 0); 
MPI_Recv(x from process 0); 
} 

क्या इस मामले में होता है पर उदाहरण देखने के लिए कॉल प्राप्त? प्रक्रिया 0 प्रक्रिया को 1 तक अवरुद्ध करता है और प्रक्रिया 1 तक ब्लॉक भेजता है, प्रक्रिया 0 0 को प्रोसेस करने के लिए 0 भेजता है और प्रक्रिया 0 तक ब्लॉक करता है, प्रक्रिया 0 अवरुद्ध होती है, इसलिए प्रक्रिया को अवरुद्ध कर दिया जाता है, जब तक कि आप 2 प्रक्रियाओं को मार नहीं देते हैं

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