私の盲目的な推測が正しく、上で入力した内容が正確であると仮定すると、のサイズは(ではなく)とは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);
}
上記のコードは、1次元および2次元配列の場合、手動で保守する代わりに、実際に送信するTのコピーの数を計算します。
のようなスライスでも機能し&A[low_bound], upper_bound-lower_bound
ます。
注意したいことの1つは、配列の終わりを超えて吹き飛ばすことです。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);
}
この場合、配列を直接渡してから、読み取りを開始および終了する場所を指定します。利点は、アレイに実際に送信するデータがあること、またはデータが到着する余地があることを確認することです。
(これらの2つの関数は、上記の関数に依存しています)
分散した状況では、説明的なアサートのロギングメカニズムを作成する必要があります。
上記のコードの使用例は次のとおりです。
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
とrecvの同上。