Ошибка сегментации в программе C с использованием MPI

Мой код ниже пытается отобразить набор целых чисел в массиве с несколькими параллельными процессорами. Я смущен, почему он продолжает получать ошибку сегментации. Я использую Убунту 17.10. Любая помощь будет принята с благодарностью.

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define IN 16   //input size

int main(int argc, char** argv){
   // Initialize the MPI environment
   MPI_Init(&argc, &argv);
   MPI_Win win;
   // Find out rank, size
   int id;  //process id
   MPI_Comm_rank(MPI_COMM_WORLD, &id);
   int p;   //number of processes
   MPI_Comm_size(MPI_COMM_WORLD, &p);

   srand(time(0));
   int mapper[IN];
   int toMap[IN];
   int result[IN];
   if(id==0){
       for(int n=0; n<IN; n++){   //predecided map values
           toMap[n] = rand()%IN;
           mapper[n] = rand()%101;
           printf("[%d, %d]", n, mapper[n]);
       }
       printf("\n");
   }

   int d = IN/p;
   int i = id*d;
   while(i<id*d+d && i<IN){
        result[i] = mapper[toMap[i]];
        i++;
   }
   MPI_Barrier(MPI_COMM_WORLD);
   if(id == 0){
       for(int n=0; n<IN; n++){   //map results
           printf("[%d -> %d]\n", toMap[n], result[n]);
       }
   }
   MPI_Finalize();
   return 0;
}

Когда я запускаю программу, используя:

mpiexec -np 2 parallelMap

Я получаю сообщение об ошибке:

[sanjiv-Inspiron-5558:00943]     *** Process received signal ***
[sanjiv-Inspiron-5558:00943] Signal: Segmentation fault (11)
[sanjiv-Inspiron-5558:00943] Signal code: Address not mapped (1)
[sanjiv-Inspiron-5558:00943] Failing at address: 0x7ffecfc33a90
[sanjiv-Inspiron-5558:00943] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x13150)[0x7f8c74400150]
[sanjiv-Inspiron-5558:00943] [ 1] parallelMap(+0xbf2)[0x5652d5561bf2]
[sanjiv-Inspiron-5558:00943] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f8c7402e1c1]
[sanjiv-Inspiron-5558:00943] [ 3] parallelMap(+0x99a)[0x5652d556199a]
[sanjiv-Inspiron-5558:00943] *** End of error message ***
--------------------------------------------------------------------------
mpiexec noticed that process rank 1 with PID 0 on node sanjiv-Inspiron-5558 exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------

person Sanjiv Pradhanang    schedule 28.01.2018    source источник


Ответы (1)


В программе MPI каждый процесс выполняет один и тот же код, но в отдельной области памяти.

В вашем коде у каждого процесса MPI есть свои int mapper[IN], они не имеют отношения друг к другу. Здесь вы используете

while(i<id*d+d && i<IN){
    result[i] = mapper[toMap[i]];
    i++;
}

для всех процессов, но только процесс id == 0 инициализировал эти массивы. Для других процессов значения в этих массивах являются мусором, что приводит к вашей ошибке сегментации.

Вы даже не вызвали ни одной подпрограммы связи MPI. На самом деле связь MPI достигается путем вызова ее подпрограммы связи, например MPI_Send(), MPI_Bcast(). Процесс id=1 не знает значения массивов в процессе id=0. Ничего не делается автоматически.

person llllllllll    schedule 28.01.2018
comment
Спасибо. Это устранило ошибки сегментации. Я хотел бы задать еще один вопрос. Поскольку я пытаюсь использовать одни и те же значения сопоставления для каждого процесса, как мне заставить все процессы генерировать одинаковые значения для преобразователя в каждом процессе. Вот почему я пытался использовать этот цикл только в одном процессе, чтобы значение этого массива было одинаковым для всех процессов. Или, я думаю, мой вопрос в том, по какому шаблону я отправляю и получаю значения среди них. Еще раз спасибо, что уделили этому время. - person Sanjiv Pradhanang; 30.01.2018
comment
Один процесс генерирует его, чем транслирует всем. См. 2 ссылки, которые я написал в ответе. - person llllllllll; 30.01.2018
comment
Я пошел по этому пути раньше, это как бы заканчивается тем, что массив результатов переопределяется любым процессом, который приходит последним. Я прав в этом? Что массив результатов отличается для каждого процесса? Поскольку каждый процесс работает с некоторыми частями массива, я отчаянно пытаюсь вернуть разделы результирующего массива из каждого процесса и объединить их в один. - person Sanjiv Pradhanang; 30.01.2018
comment
Это только кажется таким сложным. - person Sanjiv Pradhanang; 30.01.2018
comment
Нет. Если вы правильно используете MPI_Bcast(), после этого вызова передаваемый массив для всех процессов в MPI_COMM_WORLD будет содержать одно и то же значение. Вам необходимо ознакомиться с API MPI. И кстати, параллельное программирование действительно непросто. - person llllllllll; 30.01.2018
comment
Я обязательно попытаюсь получить массив результатов одним куском, заставив каждый процесс транслировать его. Я не делал этого раньше. Спасибо! - person Sanjiv Pradhanang; 30.01.2018
comment
Вам нужно передать массивы toMap и mapper, а затем собрать массивы result (под) - person Gilles Gouaillardet; 30.01.2018