2016-04-04 2 views
0

У меня есть 4 пути к файлу в global_filetable, и я пытаюсь разделить 2 pilepaths на каждый процесс.MPI - рассеяние файловых путей к процессам

Процесс 0 имеют правильные 2 пути, но есть что-то странное в процессе 1 (нуль) ...

EDIT: Вот полный код:

#include <stdio.h> 
#include <limits.h> // PATH_MAX 
#include <mpi.h> 

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

    char** global_filetable = (char**)malloc(4 * PATH_MAX * sizeof(char)); 
    for(int i = 0; i < 4; ++i) { 
     global_filetable[i] = (char*)malloc(PATH_MAX *sizeof(char)); 
     strncpy (filetable[i], "/path/", PATH_MAX); 
    } 

    /*for(int i = 0; i < 4; ++i) { 
     printf("%s\n", global_filetable[i]); 
    }*/ 

    int rank, size; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    char** local_filetable = (char**)malloc(2 * PATH_MAX * sizeof(char)); 

    MPI_Scatter(global_filetable, 2*PATH_MAX, MPI_CHAR, local_filetable, 2*PATH_MAX , MPI_CHAR, 0, MPI_COMM_WORLD); 
    { 

     /* now all processors print their local data: */ 
     for (int p = 0; p < size; ++p) { 
      if (rank == p) { 
       printf("Local process on rank %d is:\n", rank); 
       for (int i = 0; i < 2; i++) { 
        printf("path: %s\n", local_filetable[i]); 
       } 
      } 
      MPI_Barrier(MPI_COMM_WORLD); 
     } 
    } 

    MPI_Finalize(); 
    return 0; 
} 

Выход:

Local process on rank 0 is: 
path: /path/ 
path: /path/ 
Local process on rank 1 is: 
path: (null) 
path: (null) 

У вас есть идеи, почему у меня эти нули?

ответ

1

Во-первых, ваше распределение противоречива:

char** local_filetable = (char**)malloc(2 * PATH_MAX * sizeof(char)); 

Тип char** указывает на массив char*, но выделить непрерывный блок памяти, который будет указывать на char*.

Самый простой способ - использовать непрерывную память как char* для глобальных и местных filetable. В зависимости от того, что на самом деле делает get_filetable(), вам, возможно, придется преобразовать. Вы можете тогда индекс так:

char* entry = &filetable[i * PATH_MAX] 

Вы можете просто разлетаются, как это:

MPI_Scatter(global_filetable, 2 * PATH_MAX, MPI_CHAR, 
      local_filetable, 2 * PATH_MAX, MPI_CHAR, 0, MPI_COMM_WORLD); 

Обратите внимание, что нет более смещения, каждый ранг просто получает размера кусок, равный в непрерывной памяти ,

Следующим шагом будет определение структуры C и MPI, инкапсулирующей PATH_MAX символов, чтобы вы могли избавиться от постоянного использования PATH_MAX и индексации сырой нефти.

Я думаю, что это намного приятнее (менее сложное, меньше управления памятью), чем использование фактического char**. Вам понадобится только это, если проблема с памятью или избыточной передачей данных станет проблемой.

P.S. Обязательно никогда не помещайте более PATH_MAX - 1 символов в записи filetable, чтобы сохранить пространство для хвоста. \0.

0

Хорошо, я глуп.

char global_filetable[NUMBER_OF_STRINGS][PATH_MAX]; 

for(int i = 0; i < 4; ++i) { 
    strcpy (filetable[i], "/path/"); 
} 
char local_filetable[2][PATH_MAX]; 

Теперь это работает!

+0

Это не имеет ничего общего с * глупым *, но все с пониманием указателей, указателей на указатели, распределения динамической памяти и статических 2D-массивов. Вы теперь понимаете, почему он не работал раньше и работает сейчас? – Zulan

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