簡體   English   中英

如何通過Boost :: MPI發送2d C樣式數組?

[英]How to send 2d C style array over Boost::MPI?

我有double A[B_ROWS][B_COLUMNS]; 在C API中,我使用了類似的東西:

MPI_Isend(&A[low_bound][0], (upper_bound - low_bound) * A_COLUMNS, MPI_DOUBLE, i, MASTER_TO_SLAVE_TAG + 2, MPI_COMM_WORLD, &request);

 MPI_Recv(&A[low_bound][0], (upper_bound - low_bound) * A_COLUMNS, MPI_DOUBLE, 0, MASTER_TO_SLAVE_TAG + 2, MPI_COMM_WORLD, &status);

現在使用boost :: mpi我嘗試:

world.isend(i, TO_SLAVE_TAG + 2, &A[low_bound][0], (upper_bound - low_bound) * A_COLUMNS);

world.recv(0, TO_SLAVE_TAG + 2, &A[low_bound][0], (upper_bound - low_bound) * A_COLUMNS);

但我的應用程序不斷失敗,並出現以下問題:

rank 1 in job 10  master_39934   caused collective abort of all ranks
  exit status of rank 1: killed by signal 11

這意味着seg fault ,請注意,原始C應用程序可以根據需要運行,而我當前更改的只是使用api-周圍沒有任何邏輯。

那么,通過boost :: mpi發送2D C樣式數組的正確方法是什么?

假設我的盲目猜測是正確的,並且您在上面鍵入的內容是正確的,則A的大小與A_COLUMNS (相反, A具有B_COLUMNS )。 如果是這樣,下面的代碼將修復這種“不同步”錯誤:

template<typename World, typename T>
void isend( World& w, int dest, int tag, T const* t, size_t n = 1) {
  world.isend(dest, tag, &t, n);
}
template<typename World, typename T, size_t aSize>
void isend( World& w, int dest, int tag, T const (*arr1)[aSize], size_t n = 1) {
  world.isend(dest, tag, &(*arr)[0], n*aSize);
}
template<typename World, typename T, size_t aSize, size_t bSize>
void isend( World& w, int dest, int tag, T const (*arr2)[aSize][bSize], size_t n = 1) {
  world.isend(dest, tag, &(*arr)[0][0], n*aSize*bSize);
}

template<typename World, typename T>
void recv( World& w, int dest, int tag, T* t, size_t n = 1) {
  world.recv(dest, tag, &t, n);
}
template<typename World, typename T, size_t aSize>
void recv( World& w, int dest, int tag, T (*arr1)[aSize], size_t n = 1) {
  world.recv(dest, tag, &(*arr)[0], n*aSize);
}
template<typename World, typename T, size_t aSize, size_t bSize>
void recv( World& w, int dest, int tag, T (*arr2)[aSize][bSize], size_t n = 1) {
  world.recv(dest, tag, &(*arr)[0][0], n*aSize*bSize);
}

上面的代碼將針對一維和二維數組,計算出您真正想要發送多少個T副本,而不必手動維護。

它甚至適用於切片,例如&A[low_bound], upper_bound-lower_bound

您可能要注意的一件事是超出數組的末尾。 您的C代碼很可能超出數組末尾,但是那里沒有任何重要內容,因此它得以幸免。 在C ++代碼中,您可能在那里有一個對象,然后死亡而不是生存。

另一種方法可能是編寫一個同時包含切片上限和下限的函數,如下所示:

template<typename World, typename T, size_t N>
void isend_slice( World& w, int dest, int tag, T const (&t)[N], size_t start=0, size_t end=N ) {
  Assert( end <= N && start < end );
  isend(world, dest, tag, &(t[start]), end-start);
}
template<typename World, typename T, size_t N>
void recv_slice( World& w, int dest, int tag, T (&t)[N], size_t start=0, size_t end=N ) {
  Assert( end <= N && start < end );
  recv(world, dest, tag, &(t[start]), end-start);
}

在這種情況下,您將直接傳遞一個數組,然后說出您想開始和結束讀取的位置。 這樣做的好處是,我可以檢查數組是否確實有要發送的數據,或是否有數據可以到達的空間。

(這兩個功能取決於上面的功能)

在分布式情況下,您想為您的Asserts生成描述性的日志記錄機制。

這是上述代碼的示例用法:

int array[10];
int array2[10][10];
isend(world, dest, tag+0, &int(7)); // tag is an int
isend(world, dest, tag+1, &array); // tag+1 is a 10 int array
isend(world, dest, tag+2, &array2); // tag+2 is a 100 int array
isend(world, dest, tag+1, &(array2[5])); // tag+1 is a 10 int array
isend_slice(world, tag+3, 0, array2, 7, 11); // asserts, but its a 40 int array

和同上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM