- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在我的矩阵加法代码中,我使用 ISend 和 Tag 1 将下限传输到其他进程,但是当我编译代码时,所有其他从属进程都声称具有相同的下限。我不明白为什么?
输出:
I am process 1 and I received 1120 as lower bound
I am process 1 and my lower bound is 1120 and my upper bound is 1682
I am process 2 and I received 1120 as lower bound
I am process 2 and my lower bound is 1120 and my upper bound is 1682
Process 0 here: I am sending lower bound 0 to process 1
Process 0 here: I am sending lower bound 560 to process 2
Process 0 here: I am sending lower bound 1120 to process 3
Timings : 13.300698 Sec
I am process 3 and I received 1120 as lower bound
I am process 3 and my lower bound is 1120 and my upper bound is 1682
代码:
#define N_ROWS 1682
#define N_COLS 823
#define MASTER_TO_SLAVE_TAG 1 //tag for messages sent from master to slaves
#define SLAVE_TO_MASTER_TAG 4 //tag for messages sent from slaves to master
void readMatrix();
int rank, nproc, proc;
double matrix_A[N_ROWS][N_COLS];
double matrix_B[N_ROWS][N_COLS];
double matrix_C[N_ROWS][N_COLS];
int low_bound; //low bound of the number of rows of [A] allocated to a slave
int upper_bound; //upper bound of the number of rows of [A] allocated to a slave
int portion; //portion of the number of rows of [A] allocated to a slave
MPI_Status status; // store status of a MPI_Recv
MPI_Request request; //capture request of a MPI_Isend
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
double StartTime = MPI_Wtime();
// -------------------> Process 0 initalizes matrices and sends work portions to other processes
if (rank==0) {
readMatrix();
for (proc = 1; proc < nproc; proc++) {//for each slave other than the master
portion = (N_ROWS / (nproc - 1)); // calculate portion without master
low_bound = (proc - 1) * portion;
if (((proc + 1) == nproc) && ((N_ROWS % (nproc - 1)) != 0)) {//if rows of [A] cannot be equally divided among slaves
upper_bound = N_ROWS; //last slave gets all the remaining rows
} else {
upper_bound = low_bound + portion; //rows of [A] are equally divisable among slaves
}
//send the low bound first without blocking, to the intended slave
printf("Process 0 here: I am sending lower bound %i to process %i \n",low_bound,proc);
MPI_Isend(&low_bound, 1, MPI_INT, proc, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD, &request);
//next send the upper bound without blocking, to the intended slave
MPI_Isend(&upper_bound, 1, MPI_INT, proc, MASTER_TO_SLAVE_TAG + 1, MPI_COMM_WORLD, &request);
//finally send the allocated row portion of [A] without blocking, to the intended slave
MPI_Isend(&matrix_A[low_bound][0], (upper_bound - low_bound) * N_COLS, MPI_DOUBLE, proc, MASTER_TO_SLAVE_TAG + 2, MPI_COMM_WORLD, &request);
}
}
//broadcast [B] to all the slaves
MPI_Bcast(&matrix_B, N_ROWS*N_COLS, MPI_DOUBLE, 0, MPI_COMM_WORLD);
// -------------------> Other processes do their work
if (rank != 0) {
//receive low bound from the master
MPI_Recv(&low_bound, 1, MPI_INT, 0, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD, &status);
printf("I am process %i and I received %i as lower bound \n",rank,low_bound);
//next receive upper bound from the master
MPI_Recv(&upper_bound, 1, MPI_INT, 0, MASTER_TO_SLAVE_TAG + 1, MPI_COMM_WORLD, &status);
//finally receive row portion of [A] to be processed from the master
MPI_Recv(&matrix_A[low_bound][0], (upper_bound - low_bound) * N_COLS, MPI_DOUBLE, 0, MASTER_TO_SLAVE_TAG + 2, MPI_COMM_WORLD, &status);
printf("I am process %i and my lower bound is %i and my upper bound is %i \n",rank,low_bound,upper_bound);
//do your work
for (int i = low_bound; i < upper_bound; i++) {
for (int j = 0; j < N_COLS; j++) {
matrix_C[i][j] = (matrix_A[i][j] + matrix_B[i][j]);
}
}
//send back the low bound first without blocking, to the master
MPI_Isend(&low_bound, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD, &request);
//send the upper bound next without blocking, to the master
MPI_Isend(&upper_bound, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG + 1, MPI_COMM_WORLD, &request);
//finally send the processed portion of data without blocking, to the master
MPI_Isend(&matrix_C[low_bound][0], (upper_bound - low_bound) * N_COLS, MPI_DOUBLE, 0, SLAVE_TO_MASTER_TAG + 2, MPI_COMM_WORLD, &request);
}
// -------------------> Process 0 gathers the work
...
最佳答案
MPI_Isend()
开始非阻塞发送。因此,修改发送的缓冲区而不检查消息是否实际发送会导致发送错误的值。
这就是您提供的代码片段中发生的情况,在进程 for (proc = 1; proc < nproc; proc++)
的循环中
proc=1 : low_bound
被计算出来。
proc=1 : low_bound
被发送(非阻塞)到进程 1。
过程=2:low_bound
被修改。消息已损坏。
存在不同的解决方案:
使用阻塞发送 MPI_Send()
.
通过创建一个包含 3 个请求的数组来检查消息是否已完成 MPI_Request requests[3]; MPI_Status statuses[3];
, 使用非阻塞发送和使用 MPI_Waitall()
检查请求的完成情况。
MPI_Isend(&low_bound, 1, MPI_INT, proc, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD, &requests[0]);
MPI_Isend(..., &requests[1]);
MPI_Isend(..., &requests[2]);
MPI_Waitall(3, requests, statuses);
看看 MPI_Scatter()
和 MPI_Scatterv()
!
执行此操作的“常规”方法是 MPI_Bcast()
矩阵的大小。然后每个进程计算其矩阵部分的大小。进程 0 计算 sendcounts
和 displs
MPI_Scatterv()
需要.
关于c - MPI : Different value received? 中的 ISend 和 Recv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39061332/
下面是一个简单的代码,它使用 Isend 将处理器 i 的数据发送到 i+1 并探测所有发送是否完成。 代码: std::vector sendbuffer; int myrank, nprocs;
本文整理了Java中cyclops.data.Zipper.isEnd()方法的一些代码示例,展示了Zipper.isEnd()的具体用法。这些代码示例主要来源于Github/Stackoverflo
需要澄清我对 Send Types 中给出的 isend 和 issend 的理解 我的理解是,一旦发送缓冲区空闲,即当所有数据都被释放时,isend 将返回。另一方面,Issend 仅在它从获取/未
本文整理了Java中bitronix.tm.internal.XAResourceHolderState.isEnded()方法的一些代码示例,展示了XAResourceHolderState.isE
我在使用 Isend 和 Ireceive 时遇到问题。我试图向所有其他处理器发送消息,然后从其他处理器接收相同类型的消息,这些处理器执行相同的 Isend 方法。 void msgs(int my_
在 related question 中我了解到执行 request = Isend(...);接收(...); request.Wait(); 不保证工作,因为 Isend 可能不会做任何事情,直到
我的 MPI_Isend 和 MPI_Irecv 代码块有问题。我需要将一个数字 Cin 发送到生产线上的下一个流程,然后当前流程才能处理它的业务。 接收进程需要接收才能继续计算,但是当我没有 MPI
一个看似愚蠢的问题,但我似乎无法以任何方式找到明确的答案。 基本问题是我是否需要为 MPI::Isend 提供相应的 MPI::Irecv? 也就是说,即使消息发送是非阻塞的,只要我在重用发送缓冲区之
当我使用 Send/Recv 时,我的代码可以工作,但是当我用 Isend/Irecv 替换 Send/Recv 时,它会产生段错误。但在去其他地方之前,我想验证一下以下代码片段是否看起来很重要。 其
当使用序列化数据对同一标签执行多个 isend/irecv 传输时,我发现 boost::mpi 出现了 MPI_ERR_TRUNCATE 错误。这些不是并发传输,即不涉及线程。同时只有不止一项未完成
我正在尝试并行生成导数矩阵。我有两个线程的整个热方程求解器,但现在我试图找出如何将底行发送到下一个级别的 rec2,并将顶行发送到上一个级别的 rec1。我试着弄乱请求矩阵中的数字,但没有任何效果。出
在我的矩阵加法代码中,我使用 ISend 和 Tag 1 将下限传输到其他进程,但是当我编译代码时,所有其他从属进程都声称具有相同的下限。我不明白为什么? 输出: I am process 1 and
我正在创建一个程序来使用 MPI 计算两个导体之间的电势。我正在使用非阻塞发送和接收,因此可以在处理器之间发送信息时进行计算。 但是,isend 和 irecv 之间的 if 语句以及包含计算的 wa
我是一名优秀的程序员,十分优秀!