将非 NULL argv 传递给 MPI_Comm_spawn
Passing non-NULL argv to MPI_Comm_spawn
假设我的程序(我们称之为 prog_A
)作为单个 MPI 进程启动。
后来我希望程序 prog_A
使用 MPI_Comm_spawn
和我传递给 prog_A
的相同参数来生成 n
MPI 进程(让我们称它们为 prog_B
)。
例如,如果我 运行 prog_A
参数 200 100 10
mpiexec -n 1 prog_A 200 100 10
我希望为 prog_B
提供相同的参数 200 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();
你的问题是你没有 NULL
终止你的 argv 列表。这是 MPI standard 的重要部分(强调已添加):
The argv argument argv is an array of strings containing arguments
that are passed to the program. The first element of argv is the first
argument passed to command, not, as is conventional in some contexts,
the command itself. The argument list is terminated by NULL in C and
C++ and an empty string in Fortran. In Fortran, leading and trailing
spaces are always stripped, so that a string consisting of all spaces
is considered an empty string. The constant MPI_ARGV_NULL may be used
in C, C++ and Fortran to indicate an empty argument list. In C and
C++, this constant is the same as 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();
}
您根本不需要复制参数向量。您所要做的就是利用 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
以跳过第一个参数(程序名称)。该代码的好处是它可以处理传递给原始程序的任意数量的参数。
假设我的程序(我们称之为 prog_A
)作为单个 MPI 进程启动。
后来我希望程序 prog_A
使用 MPI_Comm_spawn
和我传递给 prog_A
的相同参数来生成 n
MPI 进程(让我们称它们为 prog_B
)。
例如,如果我 运行 prog_A
参数 200 100 10
mpiexec -n 1 prog_A 200 100 10
我希望为 prog_B
提供相同的参数 200 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();
你的问题是你没有 NULL
终止你的 argv 列表。这是 MPI standard 的重要部分(强调已添加):
The argv argument argv is an array of strings containing arguments that are passed to the program. The first element of argv is the first argument passed to command, not, as is conventional in some contexts, the command itself. The argument list is terminated by NULL in C and C++ and an empty string in Fortran. In Fortran, leading and trailing spaces are always stripped, so that a string consisting of all spaces is considered an empty string. The constant MPI_ARGV_NULL may be used in C, C++ and Fortran to indicate an empty argument list. In C and C++, this constant is the same as 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();
}
您根本不需要复制参数向量。您所要做的就是利用 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
以跳过第一个参数(程序名称)。该代码的好处是它可以处理传递给原始程序的任意数量的参数。