将非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
)。
例如,如果我使用参数200 100 10
运行prog_A
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标准的重要部分(重点添加):
argv参数argv是包含参数的字符串数组传递给程序。argv的第一个元素是传递给命令的参数,而不是像某些上下文中的传统情况那样,命令本身参数列表在C和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();
}
您根本不需要复制参数向量。您所要做的就是使用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
跳过第一个参数(程序名称)。该代码的好处是,它可以处理传递给原始程序的任意数量的参数。
相关文章:
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- MPI突然停止了对多个核心的操作
- 设置 Visual Studio for MPI: 找不到标识符错误
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- 重载 MPI 中的运算符 ()
- MPI:检查是否有任何进程已终止
- 使用 pybind11 共享 MPI 通信器
- 使用 CMake,Microsoft MPI 和 Visual Studio 2017 找不到 mpi.h
- 在具有 MPI 的超立方体中广播
- 通过 mpi 发送 c++ 标准::矢量<bool>
- 使用 MPI 的 C++ 中的并行 for 循环
- 如何将 OpenMP 和 MPI 导入到大型 CLion CMake 项目中?
- 如何通过Boost.MPI发送2d Boost.MultiArray的子阵列?
- HDF5 构建了并行支持,但找不到特定于 mpi 的功能
- MPI 集合通信中的指针分配
- 仅特定内核计数上的 MPI 内存损坏
- 如何在 Mac OS 上安装 boost-mpi 及其对 clang 的依赖关系?
- 从Visual Studio 2017运行MPI应用程序,每个进程在不同的cmd窗口中
- MPI::COMM::Create之后的死锁(所有进程终止)