1
votes

I meet the problem "MPI_Send(99).: Invalid tag, value is -1" while I was using VS2013 and MPIEXEC.exe to run the following code.The logic is very simple,just thread 0 send tokens to other worker thread, and then the worker thread will reset the token to 0 again.

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

int main(int argc, char **argv) {
    int myid;
    int numprocs;
    int token;
    MPI_Status  status;

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

    if (numprocs == 1) {
        printf("The number of processes for this exercise must be greater than 1!\n");
    }
    else if (myid == 0) {
        /* Master process */
        int sdrID;
        int activeWorkers;

        /* set the number of activeWorkers */
        //...
        activeWorkers = 3;
            /* while there are any active workers */
            while (activeWorkers) {
                /*receive a token from any worker*/
                MPI_Recv(&token, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

                /* obtain the sending process ID from status. */
                //...;
                //;

                /* print the message "The Master has received a token from Worker ...". */
                printf("%d",status.MPI_SOURCE);

                /* reset token to zero and send it back to the same worker */
                token = 0;
                //  //1.消息缓冲区的起始地址,这是一个指针
                //  //2.发送的指定类型的个数
                //  //3.发送数据的MPI数据类型(为了不同机器不同操作系统之间的互操作性)
                //  //4.整形,目的进程号
                //  //5.整型,消息标志(接受者可以根据这个标识来做出if不同的操作)
                MPI_Send(&token, 1, MPI_INT, status.MPI_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD);

                /* reduce the number of activeWorkers */
                activeWorkers = activeWorkers - 1;
            }
    }
    else {
        /* Worker processes */
        /* set token to 1 and send it to the Master.*/
        token = 1;
        MPI_Send(&token, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD);/////////////////

        /* receive token from the Master. */
        MPI_Recv(&token, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

        /* print a message and return */
        printf("Worker %i has received the token from the Master.\n", myid);
    }

    MPI_Finalize();

    return 0;
}
2
While you can MPI_Recv using MPI_ANY_TAG, I don't believe you can MPI_Send using it. Try changing the tags in your MPI_Sends to 1 and see what happens.wolfPack88
If you don't care about the tag in the receiver process, use 1 as tag in MPI_Send and use MPI_ANY_TAG as tag parameter in MPI_Recv. Don't use MPI_ANY_TAG in MPI_Send function.Sulav Timsina

2 Answers

6
votes

The tag in MPI_Send must be a positive integer or zero, and MPI_Send will return an error (MPI_ERR_TAG) otherwise. MPI_ANY_TAG is valid only for receive operations.

1
votes

MPI_ERR_TAG

Invalid tag argument. Tags must be non-negative;

tags in a receive (MPI_Recv, MPI_Irecv, MPI_Sendrecv, etc.) may also be MPI_ANY_TAG. The largest tag value is available through the the attribute MPI_TAG_UB.

Besides,

#define MPI_ANY_TAG            -1   /* match any message tag */