0

I've read about mpi and I'm interested in using the function MPI_Gather.

Now I'm doing this, but it's not working:

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

char *funcion (char *a) {
    sprintf(a, "asdfa%u", 2);
}

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

    MPI_Init(&argc, &argv);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    char *parcial = malloc(5*sizeof(char));
    char *total;

    if (rank == 0) {
        total = malloc(15*sizeof(char));
        parcial = "aaaaa";
    }
    else if (rank == 1) {
        parcial = "bbbbb";
    }
    else if (rank == 2) {
        parcial = "ccccc";
    }

    MPI_Gather(parcial,5,MPI_CHAR,total,15,MPI_CHAR,0,MPI_COMM_WORLD);

    if (rank == 0) {
        printf("%s",total);
    }

    MPI_Finalize();

}

Instead of printing "aaaaabbbbbccccc" it's printing only "aaaaa".

What am I doing wrong?

Sergio
  • 844
  • 2
  • 9
  • 26

2 Answers2

1

The recvcount parameter specifies the number of elements for any single receive, not the total number. Hence you should use:

MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);

Note that your understanding of strings in C is fundamentally wrong.

Firstly, every C-string needs an additional byte for the terminating null character. Hence, you must allocate 6 / 16 bytes. However, you can't send those null terminators around, otherwise the string at the master will simply end at the first terminator. But you must explicitly set total[15] = 0 to terminate the string correctly.

Secondly, parcial = "aaaaa" does not copy the string into your malloc'd memory (that is done by strncpy), instead the pointer is simply assigned to a different (non-writable) part in memory where "aaaaa\0" is stored.

Zulan
  • 21,896
  • 6
  • 49
  • 109
  • Hi, nice explanation! I fixed it and now is working, but I did this example code because I wanted to resolve a bigger (not much) problem. I thought that I could make it work correctly after your explanation but I am not able, I don't know why... I pass you the link hoping you can help me: https://stackoverflow.com/questions/42239222/gathering-strings-with-mpi-gather-openmpi-c Thank you :) – Sergio Feb 15 '17 at 01:31
0

This works nice:

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

char *funcion (char *a) {
    sprintf(a, "asdfa%u", 2);
}

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

    MPI_Init(&argc, &argv);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    void *total;
    void *parcial;

    if (rank == 0) {
        parcial = "aaaaa";
    }
    else if (rank == 1) {
        parcial = "bbbbb";
    }
    else if (rank == 2) {
        parcial = "ccccc";
    }

    MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);

    if (rank == 0) {
        printf("%s",(char*)total);
    }

    MPI_Finalize();

}
Sergio
  • 844
  • 2
  • 9
  • 26