2011-06-26 167 views
2

我在計算機編程課上只學習了大約一天的MPI,現在我必須爲它編寫一個程序。我將編寫一個將過程組織爲兩個環的程序。MPI雙環,最大值,最小值和平均值

第一環開始於過程0,並且進行到將消息發送到下一個偶數處理和最後一個過程發送其消息發送回處理0。例如,0 - > 2 - > 4 - > 6 - > 8 - > 0(但它一直到32而不是8)。下一個環是相同的,但是從過程1開始併發送到先前的關閉過程,然後返回到1.例如,1→9→7→5→3→1。

此外,我應該找到一個非常大的整數數組的最大值,最小值和平均值。我將不得不將數組分散到每個進程中,讓每個進程計算出部分答案,然後在每個進程完成後減少進程0中的答案。

最後,我在整個過程中散開,每個進程將不得不計算多少每個字母的一個部分出現。那部分對我來說真的沒有意義。但我們剛剛學會了非常基礎的東西,所以沒有花哨的東西請!這是我迄今爲止的,我已經評論了一些事情,只是提醒自己一些東西,所以如果有必要,請忽略。

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

using namespace std; 
// compile: mpicxx program.cpp 
// run: mpirun -np 4 ./a.out 
int main(int argc, char *argv[]) 
{ 
int rank;  // unique number associated with each core 
int size;  // total number of cores 
char message[80]; 
char recvd[80]; 
int prev_node, next_node; 
int tag; 
MPI_Status status; 
// start MPI interface 
MPI_Init(&argc, &argv); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

sprintf(message, "Heeeelp! from %d", rank); 

MPI_Barrier(MPI_COMM_WORLD); 
next_node = (rank + 2) % size; 
prev_node = (size + rank - 2) % size; 


tag = 0; 
if (rank % 2) { 
    MPI_Send(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD); 
    MPI_Recv(&recvd, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD, &status); 
} else { 
    MPI_Send(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD); 
    MPI_Recv(&recvd, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD, &status); 
} 

cout << "* Rank " << rank << ": " << recvd << endl; 

//max 
int large_array[100]; 

rank == 0; 
int max = 0; 

MPI_Scatter(&large_array, 1, MPI_INT, large_array, 1, MPI_INT, 0, MPI_COMM_WORLD); 
MPI_Reduce(&message, max, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); 


MPI_Finalize(); 

return 0; 

}

+1

你被困在任何特定的東西? – sarnold

+0

我只是不真誠地理解它。下面的答案幫助了很多,但我仍然沒有得到它從0到2到......返回到0.我得到0到1到2 ....這是非常令人沮喪的,因爲我很難閱讀該程序。 –

回答

4

我對此有個小小的建議:

dest = rank + 2; 
if (rank == size - 1) 
    dest = 0; 
source = rank - 2; 
if (rank == 0) 
    source = size - 1; 

我覺得destsource,姓名,將要混亂(如有消息目的地,這取決於rank的值)。使用%操作可能有助於提高清晰度:

next_node = (rank + 2) % size; 
prev_node = (size + rank - 2) % size; 

您可以選擇的基礎上rank % 2值是否接收或發送到next_nodeprev_node:一次或兩次這樣做

if (rank % 2) { 
     MPI_Send(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD, &status); 
} else { 
     MPI_Send(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD, &status); 
} 

是好的,但如果你發現你的代碼散落與這些類型的開關,它會是有意義的把這些環程序的功能,並通過作爲參數的下一個和以前的節點。

當需要分配數組和字符數組時,請記住n/size會將剩餘的n % size元素留在數組末尾,這也需要處理。 (可能在主節點上,只是爲了簡單。)

我增加了一些輸出語句(以及存儲從其他節點的消息的地方)和簡單的環項目按預期工作:

$ mpirun -np 16 ./a.out | sort -k3n 
* Rank 0: Heeeelp! from 14 
* Rank 1: Heeeelp! from 3 
* Rank 2: Heeeelp! from 0 
* Rank 3: Heeeelp! from 5 
* Rank 4: Heeeelp! from 2 
* Rank 5: Heeeelp! from 7 
* Rank 6: Heeeelp! from 4 
* Rank 7: Heeeelp! from 9 
* Rank 8: Heeeelp! from 6 
* Rank 9: Heeeelp! from 11 
* Rank 10: Heeeelp! from 8 
* Rank 11: Heeeelp! from 13 
* Rank 12: Heeeelp! from 10 
* Rank 13: Heeeelp! from 15 
* Rank 14: Heeeelp! from 12 
* Rank 15: Heeeelp! from 1 

你可以看到兩個環有,各自在自己的方向:

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

using namespace std; 
// compile: mpicxx program.cpp 
// run: mpirun -np 4 ./a.out 
int main(int argc, char *argv[]) 
{ 
    int rank;  // unique number associated with each core 
    int size;  // total number of cores 
    char message[80]; 
    char recvd[80]; 
    int prev_node, next_node; 
    int tag; 
    MPI_Status status; 
    // start MPI interface 
    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    sprintf(message, "Heeeelp! from %d", rank); 

    // cout << "Rank " << rank << ": " << message << endl; 

    MPI_Barrier(MPI_COMM_WORLD); 
    next_node = (rank + 2) % size; 
    prev_node = (size + rank - 2) % size; 


    tag = 0; 
    if (rank % 2) { 
     MPI_Send(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&recvd, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD, &status); 
    } else { 
     MPI_Send(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&recvd, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD, &status); 
    } 

    cout << "* Rank " << rank << ": " << recvd << endl; 

    //cout << "After - Rank " << rank << ": " << message << endl; 
    // end MPI interface 
    MPI_Finalize(); 

    return 0; 
} 

當談到時間來寫大的程序(排列最小值,最大值,平均值和字數),你需要稍微改變的東西:唯一的rank == 0將派我開始的時候它會發送給所有其他進程他們的難題。所有其他進程將收到,完成工作,然後發回結果。 rank == 0然後需要將來自所有人的結果整合成一個連貫的單一答案。

+0

@Alyssa,我把這些作品放到一個完整的程序中,並且隨着收到的消息擺弄(每個人都用組中的下一條消息覆蓋自己的消息)。我希望這有幫助。 – sarnold

+0

非常感謝!這是有道理的,它的工作原理!非常感謝...非常感謝。 –

+0

我編輯了上面的程序,並嘗試將最大數組放入。我有一點點開始,但我不確定如何才能真正做到最大限度。有什麼想法嗎?謝謝! –

相關問題