我尝试使用for ( a = 0; a < size; a++) {
if (rank == a) {
for ( i = 0 ; i < counts[rank]; i++) {
printf("from procs %d: %lE %lE\n", rank, xPos[i], yPos[i]);
}
}
}
MPI_Gatherv(&xPos, counts[rank], MPI_DOUBLE, &xFinal, counts, displs, MPI_DOUBLE,0, MPI_COMM_WORLD);
MPI_Gatherv(&yPos, counts[rank], MPI_DOUBLE, &yFinal, counts, displs, MPI_DOUBLE,0, MPI_COMM_WORLD);
MPI_Finalize();
FILE* f = fopen("universe.out", "wt");
for (i = 0; i < N; i++)
fprintf(f, "%lE %lE\n", xFinal[i], yFinal[i]);
fclose(f);
收集不同大小的数组,但出于某种原因,它只收集第一个处理器中的第一个对象。当我执行上面的for循环时,我从xPos和yPos获得正确的值,但是当我将数据收集到xFinal和yFinal数组并打印出值时,我只得到第一个x和y。所以基本上第一个对象有(0,0)的(x,y),我有10个对象,当它应该引用的实际对象有不同的时候,所有对象只打印出(0,0)(x, y)的
以防万一,计数[rank]和displ肯定是正确的,因为我之前用它们来分散。
我是否错误地使用了gatherrv?或者我打印不正确?
Provider=SQLOLEDB.1;Password=**mypassword**;Persist Security Info=True;User
ID=**myusername**;Initial Catalog=**catalogename**;Data
Source=**datasourcename**;Use Procedure for Prepare=1;Auto
Translate=True;Packet Size=4096;Workstation ID=**workstationid**;Use
Encryption for Data=False;Tag with column collation when possible=False
答案 0 :(得分:2)
您似乎正在同时编写所有级别的文件。您应该将文件编写代码放在if (rank == 0) { ... }
中,只允许等级0写入:
if (rank == 0)
{
FILE* f = fopen("universe.out", "wt");
for (i = 0; i < N; i++)
fprintf(f, "%lE %lE\n", xFinal[i], yFinal[i]);
fclose(f);
}
否则文件的内容可能是任何内容。
答案 1 :(得分:0)
在我通常的MPI-IO倡导者角色中,请考虑MPI-IO这类问题。您可以通过让每个进程写入文件来完全跳过聚集。此外,如果N很大,则不需要N个文件操作。让MPI(直接或通过图书馆)让您的生活更轻松。
首先,基于文本的输出格式真的是你(和你的合作者)想要的吗?如果universe.out变得足够大以至于您想要并行读取它,那么您将面临跨处理器分解文件的挑战。考虑并行HDF5(phdf5)或paralllel-netcdf(pnetcdf)或任何其他具有自描述便携式文件格式的高级库。
这是一个如何写出所有x值然后写出所有y值的示例。
#include <stdio.h>
#include <mpi.h>
#include <unistd.h> //getpid
#include <stdlib.h> //srandom, random
#define MAX_PARTS 10
int main(int argc, char **argv) {
int rank, nprocs;
MPI_Offset nparts; // more than 2 billion particle possible
int i;
double *x, *y;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Offset start=0, x_end;
MPI_Info info;
MPI_File fh;
MPI_Status status;
srandom(getpid());
/* demonstrate this works even when particles are not evenly
* distributed over the processes */
nparts=((double)random()/RAND_MAX)*MAX_PARTS;
x = malloc(nparts*sizeof(*x));
y = malloc(nparts*sizeof(*y));
for (i = 0; i< nparts; i++) {
/* just some bogus data to see what happens */
x[i] = rank*100+i;
y[i] = rank*200+i;
}
/* not using this now. might tune later if needed */
MPI_Info_create(&info);
MPI_File_open(MPI_COMM_WORLD, "universe.out",
MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &fh);
MPI_File_set_view(fh, 0, MPI_DOUBLE, MPI_DOUBLE, "native", info);
MPI_Scan(&nparts, &start, 1, MPI_OFFSET, MPI_SUM, MPI_COMM_WORLD);
/* MPI_Scan is a prefix reduction: remove our contribution */
x_end = start; /* only the last rank will use this in the bcast below */
start -= nparts;
MPI_Bcast(&x_end, 1, MPI_OFFSET, nprocs-1, MPI_COMM_WORLD);
MPI_File_write_at_all(fh, start, x, nparts, MPI_DOUBLE, &status);
MPI_File_write_at_all(fh, start+x_end, y, nparts, MPI_DOUBLE, &status);
MPI_Info_free(&info);
MPI_File_close(&fh);
MPI_Finalize();
}
可以将x数组和y数组写成(x,y)值对,但是 有点复杂(你必须制作一个MPI数据类型)。
Parallel-NetCDF有&#34;操作组合&#34;这样做的优化 您。 Parallel-HDF5有一个&#34;多数据集i / o&#34;工作中的优化 下一个版本。通过这些优化,您可以定义一个3d数组 x和y的一个维度和#34;粒子标识符&#34;的第三个维度。那么你 可以发布x值的操作,y值的操作,和 让图书馆将所有这些组合成一个电话。