Dinning philosophers problem MPI C++. Everytime process 0 exit without using finalize

0

I have some troubles with solving of the problem and i dont know what to do here. Everytime when i compile this code i get the same error : "job aborted: [ranks] message

[0] process exited without calling finalize

[1-5] terminated

---- error analysis -----

[0] on USER-PC Philosophers.exe ended prematurely and may have crashed. exit code 0x80000003"

The code:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <list>
#include "mpi.h"
#define FORK_REQUEST 1
#define FORK_RESPONSE 2
#define FORK_RELEASE 3

int main(int argc, char** argv) {
    int rank;
    int size;
    //init MPI
    if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
        return 1;
    }
    if (MPI_Comm_size(MPI_COMM_WORLD, &size) != MPI_SUCCESS) {
        MPI_Finalize();
        return 2;
    }
    if (MPI_Comm_rank(MPI_COMM_WORLD, &rank) != MPI_SUCCESS) {
        MPI_Finalize();
        return 3;
    }

    if (!rank) {
        printf("Hello from table %d \n", rank);
        int in_buffer[1];
        int out_buffer[1];
        int philosopher;
        MPI_Status status;

        std::list<int> queue;

        bool* fork = new bool[size - 1];
        for (int i = 0; i < size - 1; i++) fork[i] = true; //Init all forks as free

        //Table main loop
        while (true) {
            MPI_Recv(in_buffer, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); // Recive next message
            philosopher = status.MPI_SOURCE; //Read source of message

            if (status.MPI_TAG == FORK_REQUEST) { //If Request for forks
                printf("Table got philosopher %d fork request\n", philosopher);
                if (fork[philosopher % (size - 1)] == true && fork[philosopher - 1] == true) { //If both forks are free
                    fork[philosopher % (size - 1)] = false; //Set the forks as taken
                    fork[philosopher - 1] = false;
                    MPI_Send(out_buffer, 1, MPI_REAL, philosopher, FORK_RESPONSE, MPI_COMM_WORLD); // Send Fork response to the right philosopher
                    printf("Table sent philosopher %d the forks\n", philosopher);
                }
                else //If not both forks are free
                    queue.push_back(philosopher); //Put in wait queue
            }
            if (status.MPI_TAG == FORK_RELEASE) { //If Release of forks
                fork[philosopher % (size - 1)] = true; //Set forks to free again
                fork[philosopher - 1] = true;
                printf("Table got philosopher %d fork release\n", philosopher);

                if (!queue.empty()) { //If philosopher whaiting for forks
                    for (std::list<int>::iterator it = queue.begin(); it != queue.end(); it++) { //Go through whole list of whaiting philosophers
                        philosopher = *it;
                        if (fork[philosopher % (size - 1)] == true && fork[philosopher - 1] == true) { //If one of them can get both forks
                            fork[philosopher % (size - 1)] = false;
                            fork[philosopher - 1] = false;
                            MPI_Send(out_buffer, 1, MPI_INT, philosopher, FORK_RESPONSE, MPI_COMM_WORLD); // send Fork response
                            printf("Table sent philosopher %d the forks\n", philosopher);
                            it = queue.erase(it); //Remove from wait list
                        }
                    }
                }
            }
        }
    }
    if (rank) {
        printf("Hello from philosopher %d \n", rank);
        int in_buffer[1];
        int out_buffer[1];
        MPI_Status stat;
        out_buffer[0];
        srand(time(NULL) + rank);

        //Philosopher main loop
        while (true) {
            printf("Philosopher %d is sleeping \n", rank);
            Sleep(rand() % 10); //Sleep
            printf("Philosopher %d is whaiting to eat \n", rank);

            MPI_Send(out_buffer, 1, MPI_INT, 0, FORK_REQUEST, MPI_COMM_WORLD); //Request forks
            MPI_Recv(in_buffer, 1, MPI_INT, 0, FORK_RESPONSE, MPI_COMM_WORLD, &stat); //Whait for response
            printf("Philosopher %d is eating \n", rank);
            Sleep(rand() % 10); //Eat
            printf("Philosopher %d is done eating \n", rank);
            MPI_Send(out_buffer, 1, MPI_INT, 0, FORK_RELEASE, MPI_COMM_WORLD); //Release forks
        }
    }
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();
    return 0;
}
c++
mpi
asked on Stack Overflow Mar 22, 2021 by Sad El • edited Mar 22, 2021 by Sad El

1 Answer

0

Try replacing MPI_REAL with MPI_INT.

Edit. MPI_REAL is defined for Fortran interface; in my machine it's value is different from MPI_FLOAT. See the man page. MPI_Send and MPI_Recv may return an MPI_ERR_TYPE value, which indicates "Invalid datatype argument.". So, your implementation may be checking whether the datatype of send and receive buffers are the same and signal some error.

You also have got uninitialized send/receive buffers, but this is not an error, as their values are unused.

However, I must stress that your program works fine on my machine, so what you observe must be implementation-dependent. MPI_REAL seems a good candidate for a reason for such undefined behavior.

answered on Stack Overflow Mar 22, 2021 by zkoza • edited Mar 22, 2021 by zkoza

User contributions licensed under CC BY-SA 3.0