2015-12-09 5 views
5

enter image description hereMPI_Cart_Shift.Corner पड़ोस

मैं का उपयोग कर MPI_Cart_Shift प्रक्रियाओं है कि कगार पर हैं के बीच संदेश भेजने लागू किया, घन टोपोलॉजी के साथ एक संदेश वाहक बनाने और उसके बाद घन के चेहरे चयन करना होगा। उदाहरण के लिए मैं रैंक 0 (आर 0) के साथ प्रक्रिया कर रहा हूं, मेरे पड़ोस आर 2, आर 4, आर 6 (घन के निचले चेहरे) हैं। मुझे आर 2 और आर 4 मिल सकता है, लेकिन मुझे समझ में नहीं आता कि आर 6 कैसे ढूंढें। मेरे कोड:

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

int main(int argc, char *argv[]) 
{ 
int rank, k; 
int size; 
int ndims = 3; 
int source, dest; 
int up,down,right,left,up3, down3; 

int edges[6][4] = {{0,1,5,4}, 
       {4,5,7,6}, 
       {2,3,1,0}, 
       {6,7,3,2}, 
       {1,3,7,5}, 
       {0,2,6,7}}; 

int t, incep=0; 
char processor_name[MPI_MAX_PROCESSOR_NAME]; 

MPI_Comm comm, comm3d; 
int dims[3]={0,0,0}, coords[3]={0,0,0}, 
    periods[3]={1,1,1}, reorder = 0; 


MPI_Status status; 


int user_edge; 

MPI_Init(&argc, &argv); 

MPI_Comm_size(MPI_COMM_WORLD, &size); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

MPI_Dims_create(size, ndims, dims); 


    MPI_Cart_create(MPI_COMM_WORLD, ndims, dims, periods, reorder, &comm); 


    MPI_Cart_coords(comm, rank, 3, coords); 

fflush(stdout); 
    printf("Rank %d coordinates are %d %d %d\n", rank, coords[0], coords[1], coords[2]); 
MPI_Barrier(comm); 

    int leftrank, rightrank; 
    int downrank, uprank; 

MPI_Comm_rank(comm, &rank); 
    MPI_Cart_coords(comm, rank, 2, coords); 
MPI_Cart_shift(comm, 0, -1, &downrank, &uprank); 
MPI_Sendrecv(buffer, 10, MPI_INT, downrank, 123, buffer2, 10, MPI_INT, uprank, 123, comm, &status); 
MPI_Cart_shift(comm, 1, -1, &rightrank, &leftrank); 
    MPI_Sendrecv(buffer, 10, MPI_INT, leftrank, 123, buffer2, 10, MPI_INT, rightrank, 123, comm, &status); 


printf("P:%d My neighbors are rightRank: %d downRank:%d leftRank:%d upRank:%d diagonal:%d diagonalX:%d\n", rank,rightrank,downrank,leftrank,uprank,diagonal,diagonalX); 



MPI_Finalize(); 

return 0; 

} 

मैं इस MPI_Cart_shift की तरह कुछ जोड़ने की कोशिश करेंगे (कॉम, 2, 1, & विकर्ण, & diagonalX); लेकिन आर 0 के लिए यह मुझे आर 1 दिखाता है और मैं समझता हूं .... मैं कोने पड़ोस कैसे प्राप्त कर सकता हूं?

उत्तर

2

आप जिस जानकारी की आवश्यकता है उसे ढूंढने के लिए आप एमपीआई_Cart_rank का उपयोग कर सकते हैं।

int MPI_Cart_rank(MPI_Comm comm, const int coords[], int *rank) 

यहाँ कॉम कार्तीय टोपोलॉजी के साथ एक संदेश वाहक है। कॉर्ड एक पूर्णांक सरणी (इस सरणी का आकार कार्टेशियन टोपोलॉजी के आयामों की संख्या है) जिसमें एक प्रक्रिया का समन्वय होता है (आपके मामले में, R6 के लिए 1,1,0)। फिर आउटपुट रैंक उस प्रक्रिया के वैश्विक रैंक को वापस कर देगा जो आप बाद के संचार में उपयोग कर सकते हैं।

बीटीडब्ल्यू, एमपीआई_Cart_coords विपरीत दिशा, यानी रैंक से समन्वय करने के लिए करता है।

0

आप आर 5 लेबल करना भूल गए। प्रत्यक्ष दृष्टिकोण नहीं है जिसे मैं सोच सकता हूं। 4 विकर्ण पड़ोसियों इन किया जा सकता है - (A,y+1,z+1), (A,y-1,z-1), (A,y+1,z-1) और (A,y-1,z+1):

(1) किसी भी पद जिसका निर्देशांक हैं (A,y,z) निर्देशांक पर विचार के लिए: लेकिन यहाँ एक अप्रत्यक्ष तरीका है। जाहिर है, उदाहरण के लिए एक ऋण पर विचार करते समय z-1, यह स्पष्ट है कि z-1 >= 0 और जब एक प्लस के लिए प्लस पर विचार करते हैं y+1 <= (dimension_in_y - 1)। उदाहरण के लिए आर 5 (जिसे आप लेबल करना भूल गए) पर विचार करें। एमपीआई के मुताबिक R5 ने R5(0,1,0) को निर्देशित किया है। बाहर केवल चौथे एक मौजूद जिनमें से (जो स्पष्ट है के रूप में कोई पड़ोसी नकारात्मक निर्देशांक हो सकता है और प्रत्येक 1 कम उस दिशा में आयाम से होना चाहिए समन्वय) - (0,1+1,0+1), (0,1-1,0-1),(0,1+1,0-1),(0,1-1,0+1): यह 4 विकर्ण पड़ोसियों हो सकता है। अगला बस MPI_coordinate_to_rank() क्वेरी करें।

(2) एक अन्य विधि उनके front और back पड़ोसियों के बारे में right और left पड़ोसियों (इस खराब प्रदर्शन के लिहाज से हो जाएगा) क्वेरी करने के लिए है।

(3) इसे 8 पड़ोसियों को सामान्यीकृत करने के लिए - आपको एक्स समन्वय को भी बदलना होगा - लेकिन आपका प्रश्न घन के चेहरे तक ही सीमित है।

+0

मैं अपनी पोस्ट संपादित करता हूं। – Vdovin

+0

कृपया प्रक्रिया निर्देशांक की जांच करें। वे एमपीआई कार्टेशियन निर्देशांक के अनुसार नहीं हैं। –

1

MPI_Cart_shift केवल मुख्य दिशाओं में पड़ोसियों को ढूंढ सकता है, लेकिन तिरछे नहीं - आपको इसे स्वयं लागू करना है, जो करना मुश्किल नहीं है।

// 
// The following is equivalent to 
// MPI_Cart_shift(cart_comm, i, disp, &rank_source, &rank_dest); 
// 

// Obtain the rank of the calling process and translate it into coordinates 
int rank, coords[ndims]; 
MPI_Comm_rank(cart_comm, &rank); 
MPI_Cart_coords(cart_comm, rank, ndims, coords); 

int mycoord_i = coords[i]; 

// Compute the coordinates of the destination in direction i and convert them into rank 
coords[i] = mycoord_i + disp; 
// Take care of non-periodic dimensions 
if (!periods[i] && (coords[i] >= dims[i] || coords[i] < 0)) 
    rank_dest = MPI_PROC_NULL; 
else 
    MPI_Cart_rank(cart_comm, coords, &rank_dest); 

// Compute the coordinates of the source in direction i and convert them into rank 
coords[i] = mycoord_i - disp; 
// Take care of non-periodic dimensions 
if (!periods[i] && (coords[i] >= dims[i] || coords[i] < 0)) 
    rank_source = MPI_PROC_NULL; 
else 
    MPI_Cart_rank(cart_comm, coords, &rank_source); 

नोट कैसे बाहर के लिए बाध्य जा रहा स्पष्ट रूप से गैर आवधिक आयामों के लिए संभाला जाना चाहिए: कार्तीय पारी अपने आप में एक सुविधा समारोह है कि MPI_Cart_coords और MPI_Cart_rank के लिए कॉल लपेटता से ज्यादा कुछ नहीं है।आवधिक के लिए, MPI_Cart_rank स्वयं निर्देशांक का तह करता है। आपकी कार्टेशियन टोपोलॉजी आवधिक है, इसलिए चेक छोड़ा जा सकता है (अनुशंसित नहीं)।

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

int rank, coords[ndims]; 
MPI_Comm_rank(cart_comm, &rank); 
MPI_Cart_coords(cart_comm, rank, ndims, coords); 
int my_coord1 = coords[1]; 
int my_coord2 = coords[2]; 
coords[1] = my_coord1 + 1; 
coords[2] = my_coord2 + 1; 
MPI_Cart_rank(cart_comm, coords, &rank_dest); 
coords[1] = my_coord1 - 1; 
coords[2] = my_coord2 - 1; 
MPI_Cart_rank(cart_comm, coords, &rank_source); 

जब R0 द्वारा निष्पादित rank_dest में R6 के पद आप दे देंगे। तो आपको एक अलग दिनचर्या में कोड निकालने और यह MyMPI_Cart_shift2 कॉल करते हैं:

MyMPI_Cart_shift2(cart_comm, 1, 1, 2, 1, &rank_source, &rank_dest); 

एक अन्य विकल्प, MPI_Cart_sub उपयोग करने के लिए स्लैब में कार्तीय टोपोलॉजी विभाजित करने के लिए चेहरे के समानांतर होगी। फिर आप किसी भी दिए गए स्लैब में केवल रैंक से जुड़े संचार को सीधे कर सकते हैं।

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