将非NULL argv传递给MPI_Comm_spawn

时间:2015-02-18 14:37:27

标签: c++ parallel-processing mpi

假设我的程序(让我们称之为prog_A)作为单个MPI进程启动。 后来我希望程序prog_A使用n生成prog_B MPI进程(让我们称之为MPI_Comm_spawn),并使用与prog_A相同的参数}。

例如,如果我使用参数prog_A

运行200 100 10
mpiexec -n 1 prog_A 200 100 10

我希望prog_B200 100 10提供 char ** newargv = new char*[3];//create new argv for childs newargv[0] = new char[50]; newargv[1] = new char[50]; newargv[2] = new char[50]; strcpy(newargv[0],argv[1]);//copy argv to newargv strcpy(newargv[1],argv[2]); strcpy(newargv[2],argv[3]); MPI_Comm theother; MPI_Init(&argc, &argv); MPI_Comm_spawn("prog_B",newargv,numchildprocs, MPI_INFO_NULL, 0, MPI_COMM_SELF, &theother, MPI_ERRCODES_IGNORE); MPI_Finalize();

我该怎么做?我尝试了以下但它不起作用。

{{1}}

2 个答案:

答案 0 :(得分:2)

您的问题是您没有NULL终止您的argv列表。这是MPI standard的重要部分(强调添加):

  

argv参数argv是包含参数的字符串数组   传递给程序的。 argv的第一个元素是第一个   传递给命令的参数不是,在某些情况下是传统的,   命令本身。 参数列表在C和中以NULL结尾   C ++和Fortran中的空字符串。 在Fortran中,前导和尾随   空格总是被剥离,因此包含所有空格的字符串   被认为是一个空字符串。可以使用常量MPI_ARGV_NULL   在C,C ++和Fortran中表示一个空参数列表。在C和   C ++,这个常量与NULL相同。

您只需在列表末尾添加NULL即可。这是更正后的代码(由于我的笔记本电脑上没有安装C ++绑定,因此已翻译为C语言):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mpi.h"

int main(int argc, char ** argv) {
    char ** newargv = malloc(sizeof(char *)*4);//create new argv for childs
    int numchildprocs = 1;
    MPI_Comm theother;

    MPI_Init(&argc, &argv);
    MPI_Comm_get_parent(&theother);

    if (MPI_COMM_NULL != theother) {
        fprintf(stderr, "SPAWNED!\n");
    } else {
        newargv[0] = (char *) malloc(sizeof(char)*50);
        newargv[1] = (char *) malloc(sizeof(char)*50);
        newargv[2] = (char *) malloc(sizeof(char)*50);
        newargv[3] = NULL;

        strncpy(newargv[0],argv[1], 50);//copy argv to newargv
        strncpy(newargv[1],argv[2], 50);
        strncpy(newargv[2],argv[3], 50);

        fprintf(stderr, "SPAWNING!\n");
        MPI_Comm_spawn("./prog_B",newargv,numchildprocs,
                MPI_INFO_NULL, 0, MPI_COMM_SELF, &theother,
                MPI_ERRCODES_IGNORE);
    }

    MPI_Comm_free(&theother);

    MPI_Finalize();
}

答案 1 :(得分:1)

您根本不需要复制参数向量。您所要做的就是使用C99标准的规定,这要求argv应该以NULL结尾:

MPI_Comm theother;

// Passing &argc and &argv here is a thing of the past (MPI-1)
MPI_Init(NULL, NULL);

MPI_Comm_spawn("prog_B", argv+1, numchildprocs,
         MPI_INFO_NULL, 0, MPI_COMM_SELF, &theother,
         MPI_ERRCODES_IGNORE);

MPI_Finalize();

注意使用argv+1来跳过第一个参数(程序名称)。该代码的好处是它可以处理传递给原始程序的任意数量的参数。