gpt4 book ai didi

c - 如何访问和打印分布在 MPI 工作人员中的完整 vector ?

转载 作者:太空宇宙 更新时间:2023-11-04 06:38:06 26 4
gpt4 key购买 nike

如何从 MPI 中的单个线程访问全局 vector ?

我正在使用一个库 - 具体来说,一个 ODE 求解器库 - 称为 CVODE(SUNDIALS 的一部分)。该库与 MPI 一起工作,因此多个线程并行运行。他们都在运行相同的代码。每个线程向它“旁边”的线程发送一段数据。但我希望其中一个线程 (rank=0) 在某些时候打印出数据的状态。

library includes functions这样每个线程都可以访问自己的数据(本地 vector )。但是没有访问全局 vector 的方法。

我需要在特定时间输出所有方程式的值。为此,我需要访问全局 vector 。任何人都知道如何获取 MPI vector 中的所有数据(如果可能,使用 CVODE)?

例如,这是我每个线程运行的代码

  for (iout=1, tout=T1; iout <= NOUT; iout++, tout += DTOUT) {
flag = CVode(cvode_mem, tout, u, &t, CV_NORMAL);
if(check_flag(&flag, "CVode", 1, my_pe)) break;
if (my_pe == 0) PrintData(t, u);
}
...
static void PrintData(realtype t, N_Vector u) {
I want to print data from all threads in here
}

在函数 f(我正在求解的函数)中,我使用 MPI_SendMPI_Recv 来回传递数据。但我不能在 PrintData 中真正做到这一点,因为其他进程已经提前运行。另外,我不想增加消息传递开销。我想访问 PrintData 中的全局 vector ,然后只打印出需要的内容。可能吗?

编辑:在等待更好的答案时,我对每个线程进行了编程,将数据传递回第 0 个线程。我不认为这会增加太多的消息传递开销,但如果有更好的方法,我仍然想听听各位专家的意见(我相信没有比这更糟糕的方法了!:D)。

编辑 2:尽管 angainor 的解决方案肯定更优越,但我还是坚持使用我创建的解决方案。为了将来有同样问题的人引用,这里是我如何做的基础知识:

/* Is called by all threads */
static void PrintData(realtype t, N_Vector u, UserData data) {

... declarations and such ...

for (n=1; n<=my_length; n++) {
mass_num = my_base + n;
z[mass_num - 1] = udata[n-1];
z[mass_num - 1 + N] = udata[n - 1 + my_length];
}

if (my_pe != 0) {
MPI_Send(&z, 2*N, PVEC_REAL_MPI_TYPE, 0, my_pe, comm);

} else {

for (i=1; i<npes; i++) {
MPI_Recv(&z1, 2*N, PVEC_REAL_MPI_TYPE, i, i, comm, &status);
for (n=0; n<2*N; n++)
z[n] = z[n] + z1[n];
}

... now I can print it out however I like...

return;
}

最佳答案

使用 MPI 时,各个线程无法访问“全局” vector 。它们不是线程,它们是可以运行的进程不同的物理计算机,因此无法直接访问全局数据

要执行您想要的操作,您可以将 vector 发送到其中一个 MPI 进程(您已这样做)并在那里打印它,或者按顺序打印本地工作部件。使用这样的函数:

void MPI_write_ivector(int thrid, int nthr, int vec_dim, int *v)
{
int i, j;
int curthr = 0;

MPI_Barrier(MPI_COMM_WORLD);
while(curthr!=nthr){
if(curthr==thrid){
printf("thread %i writing\n", thrid);
for(i=0; i<vec_dim; i++) printf("%d\n", v[i]);
fflush(stdout);
curthr++;
MPI_Bcast(&curthr, 1, MPI_INT, thrid, MPI_COMM_WORLD);
} else {
MPI_Bcast(&curthr, 1, MPI_INT, curthr, MPI_COMM_WORLD);
}
}
}

所有 MPI 进程应同时调用它,因为内部存在屏障和广播。本质上,该过程确保所有 MPI 进程从等级 0 开始按顺序打印它们的 vector 部分。数据没有被弄乱,因为只有一个进程在任何给定时间写入。

在上面的示例中,使用了 Broadcast,因为它在线程打印结果的顺序上提供了更大的灵 active ——当前输出的线程可以决定下一个输出的线程。你也可以跳过广播,只使用屏障

void MPI_write_ivector(int thrid, int nthr, int vec_dim, int *v)
{
int i, j;
int curthr = 0;

while(curthr!=nthr){
if(curthr==thrid){
printf("thread %i writing\n", thrid);
for(i=0; i<vec_dim; i++) printf("%d\n", v[i]);
fflush(stdout);
}
MPI_Barrier(MPI_COMM_WORLD);
curthr++;
}
}

关于c - 如何访问和打印分布在 MPI 工作人员中的完整 vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12256650/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com