c++ - 运行 mpi 时不能使用文件 i\o

标签 c++ c mpi

我在 MPI 中遇到问题,当我从 wmpiexec 运行我的 MPI 程序时,我无法生成任何文件 io。但是当我在 visual studio 中运行它时,它工作正常。 我尝试了通常看到的 fopen() 以及 mpi APIs 没有任何效果。 (文件已经存在)

/* This is an interactive version of cpi */
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(int argc, char *argv[])
{

    int  namelen, numprocs, rank;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Get_processor_name(processor_name, &namelen);
    MPI_Status status;

    MPI_File fh;
    char x='x';

    if (rank == 0) {
        MPI_File_open(MPI_COMM_SELF, "test.txt", MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
        //FILE* f = fopen("test.txt","wb+");
        //if(f==NULL){
        //printf("failed to open file\n");exit(1);
        //}
        for (int i = 0; i < 5; i++) {
            char buf[42];
            //fprintf(f,"%d \n",i);
            snprintf(buf, 42, "%d \n", i);
            MPI_File_read(fh,&x,sizeof(char), MPI_CHAR, &status);
            printf("%c",x);


        }
        getchar();
        //        fclose(f);
        MPI_File_close(&fh);
    }
    else {
        // do nothing
    }


    MPI_Finalize();
    return 0;
}

最佳答案

函数返回的错误码MPI_File_open()可以通过测试来了解文件打开失败的原因。事实上,正如该函数的文档中强调的那样:

For MPI I/O function errors, the default error handler is set to MPI_ERRORS_RETURN. The error handler may be changed with MPI_File_set_errhandler; the predefined error handler MPI_ERRORS_ARE_FATAL may be used to make I/O errors fatal. Note that MPI does not guarantee that an MPI program can continue past an error.

因此 MPI_File_open() 的默认行为不是报告错误并尝试继续,即使文件不存在。因此,检索错误代码的值并调整错误处理程序似乎是调查该问题的一种有前途的方法。这是基于您这样做的示例代码代码。可以通过mpicc main.c -o main -std=c99 -Wall编译,通过mpirun -np 2 main

运行
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// A custom error handler
void file_errhandler_fn(MPI_File * file, int * errorcode, ... );

void file_errhandler_fn(MPI_File * file, int * errorcode, ... ){

    if(*errorcode!=MPI_SUCCESS){
        //your error handler here...
        char error[MPI_MAX_ERROR_STRING+1];
        int errorlen;
        MPI_Error_string(*errorcode, error, &errorlen);
        fprintf(stderr,"error handler: %s\n",error);
        fflush(stderr);
        //visible painful death, easily spotted
        exit(1);
    }

}

int main(int argc, char *argv[])
{

    int  namelen, numprocs, rank;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Get_processor_name(processor_name, &namelen);
    MPI_Status status;

    MPI_File fh;

    //creating an error handler for the file, calling your custom function:
    MPI_Errhandler errhandler;
    MPI_File_create_errhandler(file_errhandler_fn, &errhandler);


    char x='x';

    if (rank == 0) {
        int errorcode=MPI_File_open(MPI_COMM_SELF, "test.txt", MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
        //in case the opening of the file went wrong, handle the error:
        if(errorcode!=MPI_SUCCESS){
            //your error handler here...
            char error[MPI_MAX_ERROR_STRING+1];
            int errorlen;
            MPI_Error_string(errorcode, error, &errorlen);
            fprintf(stderr,"opening file: %s\n",error);
            fflush(stderr);
            //visible painful death, easily spotted
            exit(1);
        }
        //setting custom error handlerr for further operations
        errorcode=MPI_File_set_errhandler(fh,errhandler);


        //FILE* f = fopen("test.txt","wb+");
        //if(f==NULL){
        //printf("failed to open file\n");exit(1);
        //}
        for (int i = 0; i < 5; i++) {
            char buf[42];
            //fprintf(f,"%d \n",i);
            snprintf(buf, 42, "%d \n", i);
            errorcode=MPI_File_read(fh,&x,sizeof(char), MPI_CHAR, &status);
            printf("index %d got %c",i,x);

            // the following line should compile fine, but triggers MPI_ERR_COUNT, captured by the custom error handler. 
            //errorcode=MPI_File_write(fh, &i, -1, MPI_INT, MPI_STATUS_IGNORE); 


        }
        getchar();
        //        fclose(f);
        MPI_File_close(&fh);
    }
    else {
        // do nothing
    }

    MPI_Errhandler_free(&errhandler);

    MPI_Finalize();
    return 0;
}

这样做可能无法完全解决您的问题,但它提供了一种调查问题的方法。错误代码的值是多少?如果它对您没有帮助,请告诉我,这样我就可以取消我的回答,让您的问题没有答案!

关于c++ - 运行 mpi 时不能使用文件 i\o,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47932997/

相关文章:

c - 来自 k&r 的表查找安装功能

删除注释的C程序

c++ - 使用 mpi 将矩阵写入单个 txt 文件

c - 如何在 MPI 中仅使用一个数组来组合不同宽度的子数组进行发送和接收

c++ - 给定一个 32 位数字,按某个因子缩放每个字节的有效方法是什么?

c++ - 先按键再按值遍历 `hash_multimap`

c++ - #error "SSE2 instruction set not enabled"包含 <emmintrin.h> 时

C++ : storing a 13 digit number always fails

android - 如何为 Android shell 构建可执行文件

c++ - 在 mpi c++ visual 2010 中读写