更新。现在垃圾从共享文件的末尾删除了,但是在文件中间仍然是“垃圾”,其中进程0结束写入并且进程1开始写入:
10 4 16 16 0 2 2 3 1 3 4 2 4 5 1 0 4 6 2 8 5 3 8 10 4 9 5 4 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ 10 4 16 16 1 2 6 0 3 5 2 2 2 8 1 5 6 5 6 6 4 8 9 7 6 2 1 3 6 4 10 2 5 7 7 6 10 6 5 9 9 10 6 7 5 8
然而,如果我算上这个西伯利亚人,我会到40岁。当我尝试做的时候;
offset = (length-40)*my_rank;
它有效,但它不是一个可扩展且强大的解决方案。我需要计算这个数字以获得更通用的解决方案。有人看到怎么做,这是我目前的功能:
#define MAX_BUFF 50
int write_parallel(Context *context, int num_procs, int my_rank, MPI_Status status){
int written_chars = 0;
int written_chars_accumulator = 0;
int n = context->n;
void * charbuffer = malloc(n*MAX_BUFF);
if (charbuffer == NULL) {
exit(1);
}
MPI_File file;
MPI_Offset offset;
MPI_File_open(MPI_COMM_WORLD,"test_write.txt",
MPI_MODE_CREATE|MPI_MODE_WRONLY,
MPI_INFO_NULL, &file);
written_chars = snprintf((char *)charbuffer, n*MAX_BUFF, "%d %d %d %d\n", n, context->BOX_SIDE, context->MAX_X, context->MAX_Y);
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
int i,j;
for(i=0;i<n;i++){
if(context->allNBfrom[i]>0){
written_chars = snprintf((char *)charbuffer+written_chars_accumulator, (n*MAX_BUFF - written_chars_accumulator), "%d %d %d ", i, context->x[i], context->y[i]);
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
for(j=0;j<context->allNBfrom[i];j++){
written_chars = snprintf((char *)charbuffer+written_chars_accumulator, (n*MAX_BUFF - written_chars_accumulator), "%d ", context->delaunayEdges[i][j]);
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
}
written_chars = snprintf((char *)charbuffer+written_chars_accumulator, (n*MAX_BUFF - written_chars_accumulator), "\n");
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
}
}
int length = strlen((char*)charbuffer);
offset = (length-40)*my_rank; //Why is this correct? the constant = 40 needs to be computet in some way...
//printf("proc=%d:\n%s",my_rank,charbuffer);
MPI_File_seek(file,offset,MPI_SEEK_SET);
MPI_File_write(file,charbuffer,length,MPI_CHAR,&status);
MPI_File_close(&file);
return 0;
}
她是我目前的结果,这个解决方案也是正确的:10 4 16 16 0 2 2 3 1 3 4 2 4 5 1 0 4 6 2 8 5 3 8 10 4 9 5 4 10 4 16 16 1 2 6 0 3 5 2 2 2 8 1 5 6 5 6 6 4 8 9 7 6 2 1 3 6 4 10 2 5 7 7 6 10 6 5 9 9 10 6 7 5 8
但它不会扩展,因为,我不知道如何计算数量的jiberish elemtens。有人有线索吗?
答案 0 :(得分:0)
如果我理解您的代码,您的目标是删除文本块之间的NULL-chars。在这种并行写入方法中,没有办法在不违反缓冲区安全边界的情况下解决这个问题。现在没有任何线程提前多久其他线程的输出。这使得(或/不可能)具有写入偏移的动态范围。
如果您移动偏移量,那么您将在不为该线程保留的咏叹调中写入,并且程序可能会覆盖数据。
在我看来,有两种解决方案可以解决从文件中删除空值的问题:
答案 1 :(得分:0)
offset =(length-40)* my_rank; //为什么这是正确的?常数= 40需要以某种方式计算......
您计算此方法的方法是使用MPI_Scan
。正如其他人一直在思考的那样,您需要知道每个流程将贡献多少数据。
我很确定我之前已经回答了这个问题。适应您的代码,每个进程都计算了一个长度&#39;一些字符串:
length = strlen(charbuffer);
MPI_Scan(&length, &new_offset, 1, MPI_LONG_LONG_INT,
MPI_SUM, MPI_COMM_WORLD);
new_offset -=length; /* MPI_Scan is inclusive, but that
also means it has a defined value on rank 0 */
MPI_File_write_at_all(fh, new_offset, charbuffer, length, MPI_CHAR, &status);
MPI_Scan的重要特征是它贯穿你的排名并对所有前面的排名应用一个操作(在本例中为SUM)。在通话结束后,等级0本身就是。等级1保持其自身和等级0的总和;等级2保持其自身的总和,等级1和等级0 ......等等。