MPI_ERR_RANK: неверный ранг с кластером - PullRequest
0 голосов
/ 11 октября 2018

Я делаю проект для класса, и я использовал код для последовательной сортировки Bucket из Интернета, и я пытаюсь сделать его параллельной версией с использованием OpenMPI.Этот код будет работать в кластерной системе.Когда я проверяю его, он выдает мне следующую ошибку:

"[cluster: 5379] * Произошла ошибка в MPI_Send [cluster: 5379] на коммуникатореMPI_COMM_WORLD [кластер: 5379] MPI_ERR_RANK: недопустимый ранг [кластер: 5379] * MPI_ERRORS_ARE_FATAL: ваша работа MPI теперь будет прервана "

Может кто-нибудь предложить мне, какпочинить это?

пс.Я довольно плохо разбираюсь в программировании, поэтому я не смогу ответить на некоторые вопросы по этому поводу.

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

struct bucket
{
    int count;
    int* value;
};

int compareIntegers(const void* first, const void* second)
{
    int x = *((int*)first), y = *((int*)second);
    if (x == y)
    {
        return 0;
    }
    else if (x < y)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

void bucketSort(int array[], int n)
{
    struct bucket buckets[3];
    int i, j, k;
    for (i = 0; i < 3; i++)
    {
        buckets[i].count = 0;
        buckets[i].value = (int*)malloc(sizeof(int) * n);
    }

    for (i = 0; i < n; i++)
    {
        if (array[i] < 0)
        {
            buckets[0].value[buckets[0].count++] = array[i];
        }
        else if (array[i] > 10)
        {
            buckets[2].value[buckets[2].count++] = array[i];
        }
        else
        {
            buckets[1].value[buckets[1].count++] = array[i];
        }
    }
    for (k = 0, i = 0; i < 3; i++)
    {
        // now using quicksort to sort the elements of buckets
        qsort(buckets[i].value, buckets[i].count, sizeof(int), &compareIntegers);
        for (j = 0; j < buckets[i].count; j++)
        {
            array[k + j] = buckets[i].value[j];
        }
        k += buckets[i].count;
        free(buckets[i].value);
    }

}

int main(char *argv[], int argc)
{
    int array[1000000];
    int i = 0, j, k, n;
    int num;
    //for MPI
    int numProc, rank;
    char procName[MPI_MAX_PROCESSOR_NAME];
    int nameLen;
    int chunksize;
    double start, end;
    int msgtag;

    //MPI
    MPI_Status stat;
    start = MPI_Wtime();    //timer start
    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); //process rank ,comm_world = communication of the process
    MPI_Comm_size(MPI_COMM_WORLD, &numProc); //number of process
    msgtag = 1234;

    if (rank == 0)
    {
        printf("Enter number of element to be sort: ");
        scanf("%d", &num);

        for (i = 0; i < num; i++) //random num elements
        {
            array[i] = rand();
        }

        n = i;
        printf("\nBefore Sorting\n");
        for (j = 0; j < i; j++)
        {
            printf("%d ", array[j]);
        }
        MPI_Send(&array[j], j, MPI_INT, 1, msgtag, MPI_COMM_WORLD);
    }

    if (rank == 1)
    {
        MPI_Recv(&array[j], j, MPI_INT, 0, msgtag, MPI_COMM_WORLD, &stat);
        bucketSort(array, n);
        MPI_Send(&array, n, MPI_INT, 2, msgtag, MPI_COMM_WORLD);
    }

    if (rank == 2)
    {
        MPI_Recv(&array, n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
        printf("\nAfter Sorting\n");
        for (k = 0; k < i; k++)
        {
            printf("%d ", array[k]);
        }
    }
    //MPI END
    MPI_Finalize();
    end = MPI_Wtime();  // timer end   
    double time_spent = end - start;
    printf("\ntime used for this program was %f Sec.", time_spent);

    return 0;
}

1 Ответ

0 голосов
/ 13 октября 2018

это довольно много ошибок в вашем коде.Надеюсь, что срок исполнения - понедельник…

Первый:

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

будет работать лучше, чем int main(int argc, char *argv[])

Второй :

Процесс 0 - это тот, который предназначен для чтения количества генерируемых элементов.
Затем он должен передать его всем остальным процессам, в противном случае другие процессы будут иметь неопределенное число в переменной num, верно?

Поэтому

if (rank == 0)
{
        printf("Enter number of element to be sort: ");
        fflush(stdout);
        scanf("%d", &num);
        for (i = 0; i < num; i++) //random num elements
    {
        array[i] = rand();
    }
        n = num;
        printf("\nBefore Sorting (%i)\n", n);
    for (j = 0; j < n; j++)
    {
        printf("%d ", array[j]);
    }
        fflush(stdout);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

Третье:

Избегайте повторного использования значения, включенного в цикл.Я понимаю, что после

for (j = 0; j < n; j++)
{
    printf("%d ", array[j]);
}

у вас есть

j=n

, но это не очень понятно ...

Четвертый :

Первый аргумент для MPI_Send или receive - это адрес первого элемента в массиве.Итак, прохождение

MPI_Send(&array[j], j, MPI_INT, 1, msgtag, MPI_COMM_WORLD);

и с j=n (см. Замечание выше) Я думаю, вы не получите то, что вы хотите.

То, что вам нужно, это

MPI_Send(&array[0], n, MPI_INT, 1, msgtag, MPI_COMM_WORLD);

Пятый :

MPI_Barrier ваш друг.Вывод является критической операцией, поэтому перед операцией вывода можно (необязательно) убедиться, что все процессы достигли этой точки.

if (rank == 2)
{
    MPI_Recv(&array, n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
    printf("\nAfter Sorting\n");
    for (k = 0; k < i; k++)
    {
        printf("%d ", array[k]);
    }
}

становится

if (rank == 2)
{
    MPI_Recv(&(array[0]), n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
}
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 2)
{
    printf("\nAfter Sorting\n");
    for (k = 0; k < n; k++)
    {
        printf("%d ", array[k]);
    }
}
    MPI_Barrier(MPI_COMM_WORLD);

Вывод:

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

struct bucket
{
    int count;
    int* value;
};

int compareIntegers(const void* first, const void* second)
{
    int x = *((int*)first), y = *((int*)second);
    if (x == y)
    {
        return 0;
    }
    else if (x < y)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

void bucketSort(int array[], int n)
{
    struct bucket buckets[3];
    int i, j, k;
    for (i = 0; i < 3; i++)
    {
        buckets[i].count = 0;
        buckets[i].value = (int*)malloc(sizeof(int) * n);
    }

    for (i = 0; i < n; i++)
    {
        if (array[i] < 0)
        {
            buckets[0].value[buckets[0].count++] = array[i];
        }
        else if (array[i] > 10)
        {
            buckets[2].value[buckets[2].count++] = array[i];
        }
        else
        {
            buckets[1].value[buckets[1].count++] = array[i];
        }
    }
    for (k = 0, i = 0; i < 3; i++)
    {
        // now using quicksort to sort the elements of buckets
        qsort(buckets[i].value, buckets[i].count, sizeof(int), &compareIntegers);
        for (j = 0; j < buckets[i].count; j++)
        {
            array[k + j] = buckets[i].value[j];
        }
        k += buckets[i].count;
        free(buckets[i].value);
    }

}

int main(int argc, char *argv[])
{
    int array[1000000];
    int i = 0, j, k, n;
    int num;
    //for MPI
    int numProc, rank;
    char procName[MPI_MAX_PROCESSOR_NAME];
    int nameLen;
    int chunksize;
    double start, end;
    int msgtag;

    //MPI
    MPI_Status stat;
    start = MPI_Wtime();    //timer start
    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); //process rank ,comm_world = communication of the process
    MPI_Comm_size(MPI_COMM_WORLD, &numProc); //number of process
    msgtag = 1234;

    if (rank == 0)
    {
        printf("Enter number of element to be sort: ");
        fflush(stdout);
        scanf("%d", &num);
        for (i = 0; i < num; i++) //random num elements
        {
            array[i] = rand();
        }
        n = num;
        printf("\nBefore Sorting\n");
        for (j = 0; j < n; j++)
        {
            printf("%d ", array[j]);
        }
        fflush(stdout);
    }
    MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
    if (rank == 0)
    {
        MPI_Send(&(array[0]), n, MPI_INT, 1, msgtag, MPI_COMM_WORLD);
    }
    if (rank == 1)
    {
        MPI_Recv(&(array[0]), n, MPI_INT, 0, msgtag, MPI_COMM_WORLD, &stat);
        bucketSort(array, n);
        MPI_Send(&(array[0]), n, MPI_INT, 2, msgtag, MPI_COMM_WORLD);
    }
    if (rank == 2)
    {
        MPI_Recv(&(array[0]), n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
    }
    MPI_Barrier(MPI_COMM_WORLD);
    if (rank == 2)
    {
        printf("\nAfter Sorting\n");
        for (k = 0; k < n; k++)
        {
            printf("%d ", array[k]);
        }
    }
    //MPI END
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();
    end = MPI_Wtime();  // timer end   
    double time_spent = end - start;
    printf("\ntime used for this program was %f Sec.", time_spent);

    return 0;
}

работает

mpirun -np 3 test_mpi.exe

выходы

Enter number of element to be sort: 10

Before Sorting
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421
After Sorting

424238335 596516649 719885386 846930886 1189641421 1649760492 1681692777 1714636915 1804289383 1957747793
time used for this program was 2.271976 Sec.time used for this program was 2.281183 Sec.
time used for this program was 2.277746 Sec.
...