2015-02-18 2 views
1

Предположим, что моя программа (назовем ее prog_A) начинается как один процесс MPI. И позже я хочу, чтобы программа prog_A была создана n MPI обрабатывает (назовем их prog_B), используя MPI_Comm_spawn с теми же аргументами, которые я передал prog_A.Передача не-NULL argv в MPI_Comm_spawn

Например, если я бегу prog_A с аргументами 200 100 10

mpiexec -n 1 prog_A 200 100 10 

Я хочу prog_B быть теми же argments 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(); 
+0

Что означает «это не работает»? Есть ли сообщение об ошибке? Это крушение? Он висит? –

+0

Является ли 'prog_B' в том же каталоге? –

+0

@WesleyBland Prog_A падает при вызове MPI_Comm_spawn. да ... они находятся в одном каталоге. –

ответ

2

Ваша проблема заключается в том, что вы не NULL завершить свой список ARGV. Вот важная часть MPI standard (курсив добавлен):

ARGV аргумент ARGV является массивом строк, содержащих аргументы , которые передаются программе. Первым элементом argv является первый аргумент , переданный команде, а не как обычный в некоторых контекстах сама команда. Список аргументов завершается NULL в C и C++ и пустой строкой в ​​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(); 
} 
+0

Это решает проблему. Большое спасибо !!!!! –

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 для того, чтобы пропустить первый аргумент (название программы). Преимущество этого кода в том, что он работает с любым количеством аргументов, переданных исходной программе.

Смежные вопросы