2013-11-02 74 views
1

我想創建一個新的通信器,只保留在處理中使用的等級,如果我有24個處理器可用,我只需要10個,那麼這個組只應該保持那10個,否則它將持有他們所有的人。出於某種原因,當我嘗試創建一個通信器時,一切都會執行,但只要我嘗試獲取新通信器MPI的大小或級別就會停止並出現錯誤。新通信器無效MPI

80  float **matrix; 
81  int *ranksArr; 
82  MPI_Comm default_comm; 
83  MPI_Group world_grp, new_grp; 
84  MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank); 
85  MPI_Comm_size(MPI_COMM_WORLD, &proc_avail); 
86  MPI_Comm_group(MPI_COMM_WORLD, &world_grp); 

91  compute_block_size(&block, proc_avail); 
92 
93  if(block.procsUsed == proc_avail) 
94  { 
95   ranksArr = alloc_ranks_arr(proc_avail); 
96  } 
97  else 
98  { 
99   ranksArr = alloc_ranks_arr(block.procsUsed); 
100   proc_avail = block.procsUsed; 
101  } 
102 
103  MPI_Group_incl(world_grp, proc_avail, ranksArr, &new_grp); 
104  MPI_Comm_create(MPI_COMM_WORLD, new_grp, &default_comm); 
105  //MPI_Comm_size(default_comm, &proc_avail); //ERROR, default_comm 
106 
107  MPI_Comm_rank(default_comm, &proc_rank); 
108 
111  matrix = create_matrix_sub(&block, proc_rank); 
112 
113 
114  dealloc_matrix(matrix); 

178 int* alloc_ranks_arr(int totalRanks) 
179 { 
180  int *ranksToGroup = malloc(totalRanks * sizeof(int)); 
181  int i; 
182 
183  for(i = 0; i < totalRanks ; i++) 
184  { 
185   ranksToGroup[i] = i; 
186  } 
187 
188  return ranksToGroup; 
189 } 

[羣集SRV2:24701] *在MPI_Comm_rank 出錯[羣集SRV2:24701] *上通信器MPI_COMM_WORLD [羣集SRV2:24701] * MPI_ERR_COMM:無效通信 [集羣SRV2:24701 * MPI_ERRORS_ARE_FATAL(您MPI作業將現在 中止)

它說,在文檔:

MPI_ERR_COMM通信器無效。一個常見的錯誤是在通話中使用一個空的 通信器(甚至不允許在MPI_Comm_rank中)。

但是我在調​​用Comm_rank之前創建了通信器,並且MPI_Comm_create的返回值也給了我MPI_SUCCESS。所以我不知道爲什麼會發生這種情況。

+0

好的,看了不同的樣本後,我想我明白了這個問題。其他13個處理器永遠不會被包含在該組中,因爲我只爲該組生成0-9,我懷疑這會造成新創建的comm被隊列中不屬於該組的隊員調用時失效。由於我不想使用這些處理器,因此我打算在每個級別上調用MPI_Finalize,我不會使用這些處理器。我不確定這種方法是否可以接受,但現在可能需要做。 –

回答

4

就讓我們來看看在documentation for MPI_Comm_create說:

在該進程調用了group到它不屬於的情況下,例如,MPI_GROUP_EMPTY,然後MPI_COMM_NULL返回爲newcomm

因此,即使與MPI_SUCCESSMPI_Comm_create()調用返回,處理11-24收到MPI_COMM_NULLdefault_comm,這當然是非法的任何種類的操作使用。

呼叫MPI_Comm_create後,您應該根據過程是否在新溝通者分支,理想情況下通過檢查default_comm == MPI_COMM_NULL