2015-09-28 62 views
1

我一直在嘗試使用MPI_Comm_split創建一個星型拓撲,但是當我試圖建立與所有進程的鏈接時,我似乎有問題並且存在問題。這些過程也可以連接到MPI_COMM_WORLD的p0。問題是我在該行MPI虛擬拓撲設計

error=MPI_Intercomm_create( MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM); 

的錯誤是得到一個崩潰:MPI_ERR_COMM: invalid communicator

我有和原因的想法,雖然我不知道如何解決它。看起來這是由於不屬於新通信器(NEW_COMM)的處理零呼叫引起的。如果process = 0,我試圖放置一條if語句來停止執行此行,但是由於它是一次集體調用,所以這又失敗了。

任何建議,將不勝感激。

#include <iostream> 
#include "mpi.h" 

using namespace std; 


int main(){ 

MPI_Comm NEW_COMM , INTERCOMM; 
MPI_Init(NULL,NULL); 
int world_rank , world_size,new_size, error; 

error = MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
error = MPI_Comm_size(MPI_COMM_WORLD,&world_size); 

int color = MPI_UNDEFINED; 
if (world_rank > 0) 
    color = world_rank ; 

error = MPI_Comm_split(MPI_COMM_WORLD, color , world_rank, &NEW_COMM); 

int new_rank; 
if (world_rank > 0) { 
     error = MPI_Comm_rank(NEW_COMM , &new_rank); 
     error = MPI_Comm_size(NEW_COMM, &new_size); 
    } 
    int create_tag = 99; 

    error=MPI_Intercomm_create( MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM); 

if (world_rank > 0) 
    cout<<" My Rank in WORLD = "<< world_rank <<" New rank = "<<new_rank << " size of NEWCOMM = "<<new_size <<endl; 
else 
    cout<<" Am centre "<<endl; 


    MPI_Finalize(); 

    return 0; 


} 
+0

我可能是錯的,但我相信'MPI_Intercomm_create'需要兩個_intracommunicators_作爲輸入。現在,你正在給它MPI_COMM_WORLD和NEW_COMM;一個溝通者是另一個溝通者的一個子集。我相信你應該創建一個只有'world_rank == 0'進程的第二個通信器:'ROOT_COMM'。然後調用'MPI_Intercomm_create(ROOT_COMM,0,NEW_COMM,0,create_tag,&INTERCOMM);'可能會按預期工作。 – NoseKnowsAll

回答

1

如何使用MPI拓撲?就像這樣:

#include <mpi.h> 
#include <iostream> 

int main(int argc, char *argv[]) { 
    MPI_Init(&argc, &argv); 
    int rank, size; 

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

    int indegree, outdegree, *sources, *sourceweights, *destinations, *destweights; 

    if (rank == 0) { //centre of the star 
     indegree = outdegree = size - 1; 
     sources = new int[size - 1]; 
     sourceweights = new int[size - 1]; 
     destinations = new int[size - 1]; 
     destweights = new int[size - 1]; 
     for (int i = 0; i < size - 1; i++) { 
      sources[i] = destinations[i] = i + 1; 
      sourceweights[i] = destweights[i] = 1; 
     } 
    } 
    else { // tips of the star 
     indegree = outdegree = 1; 
     sources = new int[1]; 
     sourceweights = new int[1]; 
     destinations = new int[1]; 
     destweights = new int[1]; 
     sources[0] = destinations[0] = 0; 
     sourceweights[0] = destweights[0] = 1; 
    } 

    MPI_Comm star; 
    MPI_Dist_graph_create_adjacent(MPI_COMM_WORLD, indegree, sources, sourceweights, 
            outdegree, destinations, destweights, MPI_INFO_NULL, 
            true, &star); 
    delete[] sources; 
    delete[] sourceweights; 
    delete[] destinations; 
    delete[] destweights; 

    int starrank; 

    MPI_Comm_rank(star, &starrank); 

    std::cout << "Process #" << rank << " of MPI_COMM_WORLD is process #" << starrank << " of the star\n"; 

    MPI_Comm_free(&star); 

    MPI_Finalize(); 

    return 0; 
} 

這是你之後的事情嗎?如果沒有,你的傳播者是什麼?


編輯:約MPI說明拓撲

我想澄清的是,即使該圖傳播者,呈現正因爲如此,它在許多方面沒有什麼不同,以MPI_COMM_WORLD。值得注意的是,它包含MPI_COMM_WORLD中最初出現的整套MPI過程。事實上,雖然它的星形已經被定義,並且我們沒有表示過程#1和過程#2之間的任何鏈接,例如,沒有任何東西阻止您在這兩個過程之間建立點對點通信。簡單地說,通過定義這種圖形拓撲結構,可以指示您的代碼將暴露的通信模式類型。然後,您要求圖書館嘗試重新排序物理節點上的排名,以便在您的機器/網絡的物理佈局與您表達的需求之間找到更好的匹配。這可以通過例如使用模擬退火方法最小化成本函數的算法在內部完成,但是這是昂貴的。此外,這假設網絡的實際佈局可供圖書館使用(大多數情況下並非如此)。所以在一天結束的時候,大多數時候,這個放置優化階段只是被忽略,並且最終與您輸入的索引相同......我只知道一些基於網格/圓環形的基於網絡的機器實際執行MPI_Car_create()的安置階段,但也許我已經過時了。

無論如何,底線是我明白你想與傳播者一起學習,但不要期望太多。在這裏學習的最好的事情是如何以最少和最簡單的方式得到你想要的,這是我希望我提出的。

+0

是的,謝謝。這看起來像我正在尋找的拓撲類型,因爲我只需要一箇中央進程來分發信息。您的解決方案非常簡潔。然而,我想的是更明確的方式,即爲自己的溝通者添加流程,然後告訴它根源/中心流程是誰。我在看這個的原因是因爲我想鞏固我未來創建任何其他拓撲的技能。 – Walker

+1

我嘗試了一些編輯來回答這個問題。 – Gilles