2014-12-20 4 views
0

Я пытаюсь сортировать массив случайных чисел с помощью нечетного Даже транспозиций, но я получаю ошибку сегментации при запуске моего кода:MPI ошибка отладки Сегментации

[islb:48966] *** Process received signal *** 
[islb:48966] Signal: Segmentation fault (11) 
[islb:48966] Signal code: Address not mapped (1) 
[islb:48966] Failing at address: 0x28 
[islb:48966] [ 0] /lib64/libpthread.so.0(+0xf810)[0x7fc3da4cb810] 
[islb:48966] [ 1] /lib64/libc.so.6(memcpy+0xa3)[0x7fc3da1c7cf3] 
[islb:48966] [ 2] /usr/local/lib/libopen-pal.so.6(opal_convertor_unpack+0x10b)[0x7fc3d9c372db] 
[islb:48966] [ 3] /usr/local/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_recv_request_progress_match+0x138)[0x7fc3d58507a8] 
[islb:48966] [ 4] /usr/local/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_recv_req_start+0x1b1)[0x7fc3d5850d11] 
[islb:48966] [ 5] /usr/local/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_recv+0x139)[0x7fc3d5849489] 
[islb:48966] [ 6] /usr/local/lib/libmpi.so.1(MPI_Recv+0xc0)[0x7fc3da742f40] 
[islb:48966] [ 7] oddEven[0x40115a] 
[islb:48966] [ 8] /lib64/libc.so.6(__libc_start_main+0xe6)[0x7fc3da161c36] 
[islb:48966] [ 9] oddEven[0x400c19] 
[islb:48966] *** End of error message *** 
-------------------------------------------------------------------------- 
mpirun noticed that process rank 1 with PID 48966 on node islb exited on signal 11 (Segmentation fault). 
-------------------------------------------------------------------------- 

Программа выделяет массив, это когда он возникает, чтобы рассеять его среди процессов, которые, по-видимому, возникают в результате того, что сообщение о печати сразу после вызова разнесения только печатает для процесса 0, а затем печатает сообщение об ошибке.

Вот мой код:

#include <stdio.h> 
#include <math.h> 
#include <malloc.h> 
#include <time.h> 
#include <string.h> 
#include "mpi.h" 

const int MAX = 10000; 
int myid, numprocs; 
int i, n, j, k, arrayChunk, minindex; 
int A, B; 
int temp; 

int swap(int *x, int *y) { 
    temp = *x; 
    *x = *y; 
    *y = temp; 
    return 0; 
} 

int main(int argc, char **argv) { 
    int* arr = NULL; 
    int* value = NULL; 
    MPI_Status status; 
    //int arr[] = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; 

    srand(time(0)); 
    time_t t1, t2; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &myid); 
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs); 

    if (myid == 0) { 
    printf("Enter the number of elements you would like in the array \n"); 
    scanf("%d", &n); 

    arrayChunk = n/numprocs; 
    //printf("cpus: %d, #s per cpu: %d\n", numprocs, arrayChunk); 

    //Allocate memory for the array 
    arr = malloc(n * sizeof(int)); 
    value = malloc(n * sizeof(int)); 

    // Generate an array of size n random numbers and prints them 
    printf("Elements in the array: "); 
    for (i = 0; i < n; i++) { 
     arr[i] = (rand() % 100) + 1; 
     printf("%d ", arr[i]); 
    } 
    printf("\n"); 
    time(&t1); 
    } 

    if ((n % numprocs) != 0) { 
    if (myid == 0) 
     printf("Number of Elements are not divisible by numprocs \n"); 
    MPI_Finalize(); 
    return(0); 
    } 

    // Broadcast the size of each chunk 
    MPI_Bcast(&arrayChunk, 1, MPI_INT, 0, MPI_COMM_WORLD); 
    MPI_Scatter(&arr, arrayChunk, MPI_INT, &value, arrayChunk, MPI_INT, 0, MPI_COMM_WORLD); 
    printf("Processor %d receives %d\n", myid, value[0]); 

    for (i = 0; i < numprocs; i++) { 
    if (i % 2 == 0) { 
     if (myid%2 == 0) { 
     MPI_Send(&value[0], arrayChunk, MPI_INT, myid + 1, 0, MPI_COMM_WORLD); 
     MPI_Recv(&value[arrayChunk], arrayChunk, MPI_INT, myid + 1, 0, MPI_COMM_WORLD, &status); 

     for (j = 0; j < (arrayChunk * 2 - 1); j++) { 
      minindex = j; 
      for (k = j + 1; k < arrayChunk * 2; k++) { 
      if (value[k] < value[minindex]) { 
       minindex = k; 
      } 
      } 
      if (minindex > j) { 
      swap(&value[j], &value[minindex]); 
      } 
     } 
     //printf("myid %d i: %d, %d\n", myid, i, value[0]); 
     } else { 
     MPI_Recv(&value[arrayChunk], arrayChunk, MPI_INT, myid - 1, 0, MPI_COMM_WORLD, &status); 
     MPI_Send(&value[0], arrayChunk, MPI_INT, myid - 1, 0, MPI_COMM_WORLD); 

     for (j = 0; j < (arrayChunk * 2 - 1); j++) { 
      minindex = j; 
      for (k = j + 1; k < arrayChunk * 2; k++) { 
      if (value[k] < value[minindex]) { 
       minindex = k; 
      } 
      } 
      if (minindex > j) { 
      swap(&value[j], &value[minindex]); 
      } 
     } 

     for (j = 0; j < arrayChunk; j++) { 
     swap(&value[j], &value[j + arrayChunk]); 
     } 
     //printf("myid %d i: %d, %d\n", myid, i, value[0]); 
     } 
    } else { 
     if ((myid%2 == 1) && (myid != (numprocs-1))) { 
     MPI_Send(&value[0], arrayChunk, MPI_INT, myid + 1, 0, MPI_COMM_WORLD); 
     MPI_Recv(&value[arrayChunk], arrayChunk, MPI_INT, myid + 1, 0, MPI_COMM_WORLD, &status); 

     for (j = 0; j < (arrayChunk * 2 - 1); j++) { 
      minindex = j; 
      for (k = j + 1; k < arrayChunk * 2; k++) { 
      if (value[k] < value[minindex]) { 
       minindex = k; 
      } 
      } 
      if (minindex > j) { 
      swap(&value[j], &value[minindex]); 
      } 
     } 
     //printf("myid %d i: %d, %d\n", myid, i, value[0]); 
     } else if (myid != 0 && myid != (numprocs-1)) { 
     MPI_Recv(&value[arrayChunk], arrayChunk, MPI_INT, myid - 1, 0, MPI_COMM_WORLD, &status); 
     MPI_Send(&value[0], 1, MPI_INT, myid - 1, 0, MPI_COMM_WORLD); 

     for (j = 0; j < (arrayChunk * 2 - 1); j++) { 
      minindex = j; 
      for (k = j + 1; k < arrayChunk * 2; k++) { 
      if (value[k] < value[minindex]) { 
       minindex = k; 
      } 
      } 
      if (minindex > j) { 
      swap(&value[j], &value[minindex]); 
      } 
     } 

     for (j = 0; j < arrayChunk; j++) { 
      swap(&value[j], &value[j + arrayChunk]); 
     } 
     //printf("myid %d i: %d, %d\n", myid, i, value[0]); 
     } 
    } 
    } 

    MPI_Gather(&value[0], arrayChunk, MPI_INT, &arr[0], arrayChunk, MPI_INT, 0, MPI_COMM_WORLD); 

    if (myid == 0) { 
    time(&t2); 
    printf("Sorted array: "); 
    for (i = 0; i < n; i++) { 
     printf("%d ", arr[i]); 
    } 
    printf("\n"); 
    printf("Time in sec. %f\n", difftime(t2, t1)); 
    } 

    // Free allocated memory 
    if (arr != NULL) { 
    free(arr); 
    arr = NULL; 

    free(value); 
    value = NULL; 
    } 
    MPI_Finalize(); 
    return 0; 
} 

Я не очень хорошо знаком с C и вполне может быть, что я использовал malloc и/или адреса и указатели неправильно, так как, например, это, вероятно, что-то просто.

Извините за количество кода, но я подумал, что было бы лучше предоставить все его, чтобы обеспечить надлежащую отладку.

+0

У вас больше шансов получить помощь, если вы предоставите пример _minimal_, который воспроизводит проблему. –

+0

эта строка, внутри функции swap(): 'temp = * x;' использует глобальную переменную «temp». Было бы гораздо лучше использовать локальную/автоматическую переменную: «int temp = * x;» Примечание: 3 исключительных действия или операции будут 1) быстрее 2) не требуется пространство стека для «temp» – user3629249

+0

: строка: arrayChunk = n/numprocs; выполняет целочисленное деление. Если numprocs больше, чем пользователь, введенный 'n', тогда результат всегда будет 0 – user3629249

ответ

0

Проблема заключается в вашей команде MPI_Scatter. Вы пытаетесь разбросать информацию и хранить ее в value, но если вы посмотрите выше этого кода, только ранг 0 выделил любую память для value. Когда любой и все другие ряды пытаются хранить данные в value, вы получите ошибку сегментации (и, действительно, вы это делаете). Вместо этого удалите линию value = malloc(...); внутри блока if и положите ее после MPI_Bcast как value = malloc(arrayChunk * sizeof(int));. Я не просмотрел остальную часть кода, чтобы узнать, есть ли какие-либо проблемы в другом месте, но это, вероятно, является причиной первоначального seg-fault.

0

Я бы построил программу с информацией об отладке (скорее всего -g скомпилировать флаг), попробуйте получить coredump и попробуйте использовать отладчик gdb, чтобы найти ошибку. Corefile создается при сбое процесса, и в момент сбоя он сохраняет образ памяти процесса.

Если после сбоя программы файл coredump не создан, вам нужно выяснить, как включить его в вашей системе. Вы можете создать простую багги-программу (например, с a=x/0; или аналогичную ошибку) и немного поиграть. Coredump можно назвать core, PID.core (PID - номер разбитого процесса) или что-то подобное. Иногда достаточно установить размер основного файла tu неограниченный с использованием ulimit. Также проверьте kernel.core_* sysctl на Linux.

После того, как Вы corecump, Вы можете использовать его с gdb или аналогичной Debuger (ddd):

gdb executable_file core 
Смежные вопросы