2017-04-03 87 views
-1

計算後,使用笛卡爾拓撲將矩陣與矢量相乘。我用他們的等級和向量得到以下過程。在MPI中按元素明智地收集和收集元素

P0 (process with rank = 0) =[2 , 9]. 
P1 (process with rank = 1) =[2 , 3] 
P2 (process with rank = 2) =[1 , 9] 
P3 (process with rank = 3) =[4 , 6]. 

現在。我需要分別總結偶數等級過程的奇數那些的元素和,如下所示:

temp1目錄= [3,18]
TEMP2 = [6,9]

,然後,收集結果在不同的載體,就像這樣:

result = [3 , 18 , 6 , 9]

我attampt做到這一點是使用MPI_Reduce然後MPI_Gather這樣的:

// Previous code 
double* temp1 , *temp2; 
    if(myrank %2 == 0){ 
    BOOLEAN flag = Allocate_vector(&temp1 ,local_m); // function to allocate space for vectors 
    MPI_Reduce(local_y, temp1, local_n, MPI_DOUBLE, MPI_SUM, 0 , comm); 
    MPI_Gather(temp1, local_n, MPI_DOUBLE, gResult, local_n, MPI_DOUBLE,0, comm); 
     free(temp1); 
     } 
    else{ 
     Allocate_vector(&temp2 ,local_m); 
     MPI_Reduce(local_y, temp2, local_n , MPI_DOUBLE, MPI_SUM, 0 , comm); 
     MPI_Gather(temp2, local_n, MPI_DOUBLE, gResult, local_n, MPI_DOUBLE, 0,comm); 
     free(temp2); 
     } 

但答案不correct.It seemd該代碼求和偶數和奇數處理togather的所有元素,然後給出一個分段錯誤: Wrong_result = [21 15 0 0] 和此錯誤

** Error in ./test': double free or corruption (fasttop): 0x00000000013c7510 *** *** Error in ./test': double free or corruption (fasttop): 0x0000000001605b60 ***

+1

請參閱[如何創建最小,完整和可驗證的示例](https://stackoverflow.com/help/mcve) – Arash

回答

0

它不會像你試圖這樣做。爲了減少一部分流程的元素,你必須爲它們創建一個子通信器。在你的情況下,奇數和偶數進程共享相同的comm,因此這些操作不是在兩個獨立的進程組上,而是在聯合組上。

您應該使用MPI_Comm_split進行分割,利用這兩個新subcommunicators進行還原,終於有秩0的每個subcommunicator(讓我們調用這些領導)參加聚集了只包含這兩個另一個subcommunicator :

// Make sure rank is set accordingly 

MPI_Comm_rank(comm, &rank); 

// Split even and odd ranks in separate subcommunicators 

MPI_Comm subcomm; 
MPI_Comm_split(comm, rank % 2, 0, &subcomm); 

// Perform the reduction in each separate group 

double *temp; 
Allocate_vector(&temp, local_n); 
MPI_Reduce(local_y, temp, local_n , MPI_DOUBLE, MPI_SUM, 0, subcomm); 

// Find out our rank in subcomm 

int subrank; 
MPI_Comm_rank(subcomm, &subrank); 

// At this point, we no longer need subcomm. Free it and reuse the variable. 

MPI_Comm_free(&subcomm); 

// Separate both group leaders (rank 0) into their own subcommunicator 

MPI_Comm_split(comm, subrank == 0 ? 0 : MPI_UNDEFINED, 0, &subcomm); 
if (subcomm != MPI_COMM_NULL) { 
    MPI_Gather(temp, local_n, MPI_DOUBLE, gResult, local_n, MPI_DOUBLE, 0, subcomm); 
    MPI_Comm_free(&subcomm); 
} 

// Free resources 

free(temp); 

其結果將是在等級0的gResult在後者subcomm,這恰好是秩0 comm的,因爲進行的分割的方式。

不像預期的那麼簡單,我想,但那是在MPI中進行方便的集體操作的代價。


在一個側面節點,在代碼中所示您正在分配temp1temp2是長度local_m的,而在所有集體呼叫的長度被指定爲local_n。如果它發生local_n > local_m,那麼會發生堆損壞。

+0

謝謝。我使用了您的建議。該代碼成功運行,然後再當我試圖再次運行它仍然給出了答案,但這個錯誤:致命錯誤PMPI_Comm_free:在PMPI_Comm_free致命錯誤:無效的溝通,錯誤堆棧: PMPI_Comm_free(143):MPI_Comm_free(COMM = 0x7ffe22d63200 )失敗 PMPI_Comm_free(93):空通信器 PMPI_Comm_free中的致命錯誤:無效的通信器,錯誤堆棧:PMPI_Comm_free(143):MPI_Comm_free(comm = 0x7ffca17bd180)失敗PMPI_Comm_free(93)。:Null communicator –

+0

它似乎無法創建第一行的通信器,因爲它返回MPI_COMM_NULL –

+0

啊,當然。我的錯。在最後釋放它之前,進程應該檢查它們是否是'subcomm'的一部分。固定。 –